1 /******************************************************************************
2 * $Id$
3 *
4 * Project: MapServer
5 * Purpose: MapCache tile caching support file: Virtualearth quadkey service
6 * Author: Thomas Bonfort and the MapServer team.
7 *
8 ******************************************************************************
9 * Copyright (c) 1996-2011 Regents of the University of Minnesota.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies of this Software or works derived from this Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 *****************************************************************************/
29
30 #include "mapcache.h"
31 #include <apr_strings.h>
32 #include <math.h>
33 #include "mapcache_services.h"
34
35 /** \addtogroup services */
36
37 /** @{ */
38
39
_create_capabilities_ve(mapcache_context * ctx,mapcache_request_get_capabilities * req,char * url,char * path_info,mapcache_cfg * cfg)40 void _create_capabilities_ve(mapcache_context *ctx, mapcache_request_get_capabilities *req, char *url, char *path_info, mapcache_cfg *cfg)
41 {
42 ctx->set_error(ctx, 501, "ve service does not support capapbilities");
43 }
44
45 /**
46 * \brief parse a VE request
47 * \private \memberof mapcache_service_ve
48 * \sa mapcache_service::parse_request()
49 */
_mapcache_service_ve_parse_request(mapcache_context * ctx,mapcache_service * this,mapcache_request ** request,const char * cpathinfo,apr_table_t * params,mapcache_cfg * config)50 void _mapcache_service_ve_parse_request(mapcache_context *ctx, mapcache_service *this, mapcache_request **request,
51 const char *cpathinfo, apr_table_t *params, mapcache_cfg *config)
52 {
53 int i,x,y,z;
54 const char *layer, *quadkey;
55 mapcache_tileset *tileset = NULL;
56 mapcache_grid_link *grid_link = NULL;
57 mapcache_tile *tile;
58 mapcache_request_get_tile *req;
59
60 layer = apr_table_get(params, "layer");
61 if (layer) {
62 /*tileset not found directly, test if it was given as "name@grid" notation*/
63 char *tname = apr_pstrdup(ctx->pool, layer);
64 char *gname = tname;
65 while (*gname) {
66 if (*gname == '@') {
67 *gname = '\0';
68 gname++;
69 break;
70 }
71 gname++;
72 }
73 if (!gname) {
74 ctx->set_error(ctx, 404, "received ve request with invalid layer %s", layer);
75 return;
76 }
77 tileset = mapcache_configuration_get_tileset(config, tname);
78 if (!tileset) {
79 ctx->set_error(ctx, 404, "received ve request with invalid layer %s", tname);
80 return;
81 }
82 for (i = 0; i < tileset->grid_links->nelts; i++) {
83 mapcache_grid_link *sgrid = APR_ARRAY_IDX(tileset->grid_links, i, mapcache_grid_link*);
84 if (!strcmp(sgrid->grid->name, gname)) {
85 grid_link = sgrid;
86 break;
87 }
88 }
89 if (!grid_link) {
90 ctx->set_error(ctx, 404, "received ve request with invalid grid %s", gname);
91 return;
92 }
93 } else {
94 ctx->set_error(ctx, 400, "received ve request with no layer");
95 return;
96 }
97
98 quadkey = apr_table_get(params, "tile");
99 tile = mapcache_tileset_tile_create(ctx->pool, tileset, grid_link);
100 if (quadkey) {
101 mapcache_util_quadkey_decode(ctx, quadkey, &x, &y, &z);
102 GC_CHECK_ERROR(ctx);
103 if (z < 1 || z >= grid_link->grid->nlevels) {
104 ctx->set_error(ctx, 404, "received ve request with invalid z level %d\n", z);
105 return;
106 }
107 } else {
108 ctx->set_error(ctx, 400, "received ve request with no tile quadkey");
109 return;
110 }
111
112
113 req = (mapcache_request_get_tile*) apr_pcalloc(ctx->pool, sizeof (mapcache_request_get_tile));
114 ((mapcache_request*)req)->type = MAPCACHE_REQUEST_GET_TILE;
115 req->ntiles = 1;
116 req->tiles = (mapcache_tile**) apr_pcalloc(ctx->pool, sizeof (mapcache_tile*));
117 req->tiles[0] = tile;
118 tile->z = z;
119 switch (grid_link->grid->origin) {
120 case MAPCACHE_GRID_ORIGIN_BOTTOM_LEFT:
121 req->tiles[0]->x = x;
122 req->tiles[0]->y = grid_link->grid->levels[z]->maxy - y - 1;
123 break;
124 case MAPCACHE_GRID_ORIGIN_TOP_LEFT:
125 req->tiles[0]->x = x;
126 req->tiles[0]->y = y;
127 break;
128 case MAPCACHE_GRID_ORIGIN_BOTTOM_RIGHT:
129 req->tiles[0]->x = grid_link->grid->levels[z]->maxx - x - 1;
130 req->tiles[0]->y = y;
131 break;
132 case MAPCACHE_GRID_ORIGIN_TOP_RIGHT:
133 req->tiles[0]->x = grid_link->grid->levels[z]->maxx - x - 1;
134 req->tiles[0]->y = grid_link->grid->levels[z]->maxy - y - 1;
135 break;
136 }
137 mapcache_tileset_tile_validate(ctx, req->tiles[0]);
138 GC_CHECK_ERROR(ctx);
139 *request = (mapcache_request*) req;
140 return;
141 }
142
mapcache_service_ve_create(mapcache_context * ctx)143 mapcache_service* mapcache_service_ve_create(mapcache_context *ctx)
144 {
145 mapcache_service_ve* service = (mapcache_service_ve*) apr_pcalloc(ctx->pool, sizeof (mapcache_service_ve));
146 if (!service) {
147 ctx->set_error(ctx, 500, "failed to allocate ve service");
148 return NULL;
149 }
150 service->service.url_prefix = apr_pstrdup(ctx->pool, "ve");
151 service->service.name = apr_pstrdup(ctx->pool, "ve");
152 service->service.type = MAPCACHE_SERVICE_VE;
153 service->service.parse_request = _mapcache_service_ve_parse_request;
154 service->service.create_capabilities_response = _create_capabilities_ve;
155 return (mapcache_service*) service;
156 }
157
158 /** @} */
159 /* vim: ts=2 sts=2 et sw=2
160 */
161