1 /******************************************************************************
2  *
3  * Project:  MapCache
4  * Author:   Thomas Bonfort and the MapServer team.
5  *
6  ******************************************************************************
7  * Copyright (c) 1996-2011 Regents of the University of Minnesota.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies of this Software or works derived from this Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  *****************************************************************************/
27 
28 /*! \file mapcache.h
29     \brief global function and structure declarations
30  */
31 
32 
33 #ifndef MAPCACHE_H_
34 #define MAPCACHE_H_
35 
36 #include "mapcache-config.h"
37 #include "mapcache-version.h"
38 
39 #include <apr_tables.h>
40 #include <apr_hash.h>
41 #include <apr_reslist.h>
42 
43 #include "util.h"
44 #include "ezxml.h"
45 
46 #include "errors.h"
47 
48 
49 #include <assert.h>
50 #include <time.h>
51 #include <apr_time.h>
52 
53 
54 #define MAPCACHE_SUCCESS 0
55 #define MAPCACHE_FAILURE 1
56 #define MAPCACHE_TRUE 1
57 #define MAPCACHE_FALSE 0
58 #define MAPCACHE_TILESET_WRONG_SIZE 2
59 #define MAPCACHE_TILESET_WRONG_RESOLUTION 3
60 #define MAPCACHE_TILESET_WRONG_EXTENT 4
61 #define MAPCACHE_CACHE_MISS 5
62 #define MAPCACHE_FILE_LOCKED 6
63 #define MAPCACHE_CACHE_RELOAD 7
64 
65 #define MAPCACHE_MAX_NUM_TILES 1000
66 
67 #define MAPCACHE_USERAGENT "mod-mapcache/"MAPCACHE_VERSION
68 
69 #if defined(_WIN32) && !defined(__CYGWIN__)
70 #  define MS_DLL_EXPORT     __declspec(dllexport)
71 #else
72 #define  MS_DLL_EXPORT
73 #endif
74 
75 
76 typedef struct mapcache_image_format mapcache_image_format;
77 typedef struct mapcache_image_format_mixed mapcache_image_format_mixed;
78 typedef struct mapcache_image_format_png mapcache_image_format_png;
79 typedef struct mapcache_image_format_png_q mapcache_image_format_png_q;
80 typedef struct mapcache_image_format_jpeg mapcache_image_format_jpeg;
81 typedef struct mapcache_image_format_raw mapcache_image_format_raw;
82 typedef struct mapcache_cfg mapcache_cfg;
83 typedef struct mapcache_tileset mapcache_tileset;
84 typedef struct mapcache_cache mapcache_cache;
85 typedef struct mapcache_source mapcache_source;
86 typedef struct mapcache_buffer mapcache_buffer;
87 typedef struct mapcache_tile mapcache_tile;
88 typedef struct mapcache_metatile mapcache_metatile;
89 typedef struct mapcache_feature_info mapcache_feature_info;
90 typedef struct mapcache_request_get_feature_info mapcache_request_get_feature_info;
91 typedef struct mapcache_map mapcache_map;
92 typedef struct mapcache_http_response mapcache_http_response;
93 typedef struct mapcache_http mapcache_http;
94 typedef struct mapcache_request mapcache_request;
95 typedef struct mapcache_request_image mapcache_request_image;
96 typedef struct mapcache_request_proxy mapcache_request_proxy;
97 typedef struct mapcache_request_get_capabilities mapcache_request_get_capabilities;
98 typedef struct mapcache_forwarding_rule mapcache_forwarding_rule;
99 
100 typedef struct mapcache_request_get_tile mapcache_request_get_tile;
101 typedef struct mapcache_request_get_map mapcache_request_get_map;
102 typedef struct mapcache_service mapcache_service;
103 typedef struct mapcache_server_cfg mapcache_server_cfg;
104 typedef struct mapcache_image mapcache_image;
105 typedef struct mapcache_grid mapcache_grid;
106 typedef struct mapcache_grid_level mapcache_grid_level;
107 typedef struct mapcache_grid_link mapcache_grid_link;
108 typedef struct mapcache_rule mapcache_rule;
109 typedef struct mapcache_ruleset mapcache_ruleset;
110 typedef struct mapcache_context mapcache_context;
111 typedef struct mapcache_dimension mapcache_dimension;
112 typedef struct mapcache_requested_dimension mapcache_requested_dimension;
113 typedef struct mapcache_extent mapcache_extent;
114 typedef struct mapcache_extent_i mapcache_extent_i;
115 typedef struct mapcache_connection_pool mapcache_connection_pool;
116 typedef struct mapcache_locker mapcache_locker;
117 
118 typedef enum {
119   MAPCACHE_DIMENSION_VALUES,
120   MAPCACHE_DIMENSION_REGEX,
121   MAPCACHE_DIMENSION_POSTGRESQL,
122   MAPCACHE_DIMENSION_SQLITE,
123   MAPCACHE_DIMENSION_ELASTICSEARCH
124 } mapcache_dimension_type;
125 
126 typedef enum {
127   MAPCACHE_DIMENSION_ASSEMBLY_NONE,
128   MAPCACHE_DIMENSION_ASSEMBLY_STACK,
129   MAPCACHE_DIMENSION_ASSEMBLY_ANIMATE
130 } mapcache_dimension_assembly_type;
131 
132 
133 
134 /** \defgroup utility Utility */
135 /** @{ */
136 
137 struct mapcache_extent {
138   double minx;
139   double miny;
140   double maxx;
141   double maxy;
142 };
143 
144 struct mapcache_extent_i {
145   int minx;
146   int miny;
147   int maxx;
148   int maxy;
149 };
150 
151 
152 
153 mapcache_image *mapcache_error_image(mapcache_context *ctx, int width, int height, char *msg);
154 
155 /**
156  * \interface mapcache_context
157  * \brief structure passed to most mapcache functions to abstract common functions
158  */
159 struct mapcache_context {
160   /**
161    * \brief indicate that an error has happened
162    * \memberof mapcache_context
163    * \param c
164    * \param code the error code
165    * \param message human readable message of what happened
166    */
167   void (*set_error)(mapcache_context *ctx, int code, char *message, ...);
168 
169   void (*set_exception)(mapcache_context *ctx, char *key, char *message, ...);
170 
171   /**
172    * \brief query context to know if an error has occurred
173    * \memberof mapcache_context
174    */
175   int (*get_error)(mapcache_context * ctx);
176 
177   /**
178    * \brief get human readable message for the error
179    * \memberof mapcache_context
180    */
181   char* (*get_error_message)(mapcache_context * ctx);
182 
183   /**
184    * \brief get human readable message for the error
185    * \memberof mapcache_context
186    */
187   void (*clear_errors)(mapcache_context * ctx);
188 
189   /**
190    * \brief clear current error and store it in mapcache_error
191    * \memberof mapcache_context
192    */
193   void (*pop_errors)(mapcache_context * ctx, void **error);
194 
195   /**
196    * \brief restore error status from mapcache_error
197    * \memberof mapcache_context
198    */
199   void (*push_errors)(mapcache_context * ctx, void *error);
200 
201 
202   /**
203    * \brief log a message
204    * \memberof mapcache_context
205    */
206   void (*log)(mapcache_context *ctx, mapcache_log_level level, char *message, ...);
207 
208   const char* (*get_instance_id)(mapcache_context * ctx);
209   mapcache_context* (*clone)(mapcache_context *ctx);
210   apr_pool_t *pool;
211   mapcache_connection_pool *connection_pool;
212   char *_contenttype;
213   char *_errmsg;
214   int _errcode;
215   mapcache_cfg *config;
216   mapcache_service *service;
217   apr_table_t *exceptions;
218   int supports_redirects;
219   apr_table_t *headers_in;
220 };
221 
222 MS_DLL_EXPORT void mapcache_context_init(mapcache_context *ctx);
223 MS_DLL_EXPORT void mapcache_context_copy(mapcache_context *src, mapcache_context *dst);
224 
225 #define GC_CHECK_ERROR_RETURN(ctx) if(((mapcache_context*)ctx)->_errcode) return MAPCACHE_FAILURE;
226 #define GC_CHECK_ERROR(ctx) if(((mapcache_context*)ctx)->_errcode) return;
227 #define GC_HAS_ERROR(ctx) (((mapcache_context*)ctx)->_errcode > 0)
228 
229 /**
230  * \brief autoexpanding buffer that allocates memory from a pool
231  * \sa mapcache_buffer_create()
232  * \sa mapcache_buffer_append()
233  *
234  */
235 struct mapcache_buffer {
236   void* buf; /**< pointer to the actual data contained in buffer */
237   size_t size; /**< number of bytes actually used in the buffer */
238   size_t avail; /**< number of bytes allocated */
239   apr_pool_t* pool; /**< apache pool to allocate from */
240 };
241 
242 /* in buffer.c */
243 /**
244  * \brief create and initialize a mapcache_buffer
245  * \memberof mapcache_buffer
246  * \param initialStorage the initial size that should be allocated in the buffer.
247  *        defaults to #INITIAL_BUFFER_SIZE.
248  * \param pool the pool from which to allocate memory.
249  */
250 mapcache_buffer *mapcache_buffer_create(size_t initialStorage, apr_pool_t* pool);
251 
252 /**
253  * \brief append data
254  * \memberof mapcache_buffer
255  * \param buffer
256  * \param len the lenght of the data to append.
257  * \param data the data to append
258  */
259 int mapcache_buffer_append(mapcache_buffer *buffer, size_t len, void *data);
260 
261 /** @} */
262 
263 /** \defgroup source Sources */
264 
265 /** @{ */
266 
267 typedef enum {
268   MAPCACHE_SOURCE_WMS,
269   MAPCACHE_SOURCE_MAPSERVER,
270   MAPCACHE_SOURCE_DUMMY,
271   MAPCACHE_SOURCE_GDAL,
272   MAPCACHE_SOURCE_FALLBACK
273 } mapcache_source_type;
274 
275 /**\interface mapcache_source
276  * \brief a source of data that can return image data
277  */
278 struct mapcache_source {
279   char *name; /**< the key this source can be referenced by */
280   mapcache_extent data_extent; /**< extent in which this source can produce data */
281   mapcache_source_type type;
282   apr_table_t *metadata;
283   unsigned int retry_count;
284   double retry_delay;
285 
286   apr_array_header_t *info_formats;
287   /**
288    * \brief get the data for the metatile
289    *
290    * sets the mapcache_metatile::tile::data for the given tile
291    */
292   void (*_render_map)(mapcache_context *ctx, mapcache_source *psource, mapcache_map *map);
293 
294   void (*_query_info)(mapcache_context *ctx, mapcache_source *psource, mapcache_feature_info *fi);
295 
296   void (*configuration_parse_xml)(mapcache_context *ctx, ezxml_t xml, mapcache_source * source, mapcache_cfg *config);
297   void (*configuration_check)(mapcache_context *ctx, mapcache_cfg *cfg, mapcache_source * source);
298 };
299 
300 mapcache_http* mapcache_http_configuration_parse_xml(mapcache_context *ctx,ezxml_t node);
301 mapcache_http* mapcache_http_clone(mapcache_context *ctx, mapcache_http *orig);
302 
303 struct mapcache_http {
304   char *url; /**< the base url to request */
305   apr_table_t *headers; /**< additional headers to add to the http request, eg, Referer */
306   char *post_body;
307   size_t post_len;
308   int connection_timeout;
309   int timeout;
310   /* TODO: authentication */
311 };
312 
313 
314 
315 
316 /** \defgroup cache Caches */
317 
318 /** @{ */
319 typedef enum {
320   MAPCACHE_CACHE_DISK
321   ,MAPCACHE_CACHE_REST
322   ,MAPCACHE_CACHE_MEMCACHE
323   ,MAPCACHE_CACHE_SQLITE
324   ,MAPCACHE_CACHE_BDB
325   ,MAPCACHE_CACHE_TC
326   ,MAPCACHE_CACHE_TIFF
327   ,MAPCACHE_CACHE_COMPOSITE
328   ,MAPCACHE_CACHE_COUCHBASE
329   ,MAPCACHE_CACHE_RIAK
330 } mapcache_cache_type;
331 
332 /** \interface mapcache_cache
333  * \brief a place to cache a mapcache_tile
334  */
335 struct mapcache_cache {
336   char *name; /**< key this cache is referenced by */
337   mapcache_cache_type type;
338   apr_table_t *metadata;
339   unsigned int retry_count;
340   double retry_delay;
341 
342 
343   /**
344    * get tile content from cache
345    * \returns MAPCACHE_SUCCESS if the data was correctly loaded from the cache
346    * \returns MAPCACHE_FAILURE if the file exists but contains no data
347    * \returns MAPCACHE_CACHE_MISS if the file does not exist on the cache
348    * \memberof mapcache_cache
349    */
350   int (*_tile_get)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
351 
352   /**
353    * delete tile from cache
354    *
355    * \memberof mapcache_cache
356    */
357   void (*_tile_delete)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
358 
359   int (*_tile_exists)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
360 
361   /**
362    * set tile content to cache
363    * \memberof mapcache_cache
364    */
365   void (*_tile_set)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
366   void (*_tile_multi_set)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tiles, int ntiles);
367 
368   void (*configuration_parse_xml)(mapcache_context *ctx, ezxml_t xml, mapcache_cache * cache, mapcache_cfg *config);
369   void (*configuration_post_config)(mapcache_context *ctx, mapcache_cache * cache, mapcache_cfg *config);
370 };
371 
372 MS_DLL_EXPORT int mapcache_cache_tile_get(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
373 void mapcache_cache_tile_delete(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
374 MS_DLL_EXPORT int mapcache_cache_tile_exists(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
375 MS_DLL_EXPORT void mapcache_cache_tile_set(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
376 void mapcache_cache_tile_multi_set(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tiles, int ntiles);
377 
378 
379 
380 /**
381  * \memberof mapcache_cache_sqlite
382  */
383 mapcache_cache* mapcache_cache_sqlite_create(mapcache_context *ctx);
384 mapcache_cache* mapcache_cache_mbtiles_create(mapcache_context *ctx);
385 
386 /**
387  * \memberof mapcache_cache_bdb
388  */
389 mapcache_cache *mapcache_cache_bdb_create(mapcache_context *ctx);
390 
391 /**
392  * \memberof mapcache_cache_memcache
393  */
394 mapcache_cache* mapcache_cache_memcache_create(mapcache_context *ctx);
395 
396 /**
397  * \memberof mapcache_cache_couchbase
398  */
399 mapcache_cache* mapcache_cache_couchbase_create(mapcache_context *ctx);
400 
401 /**
402  * \memberof mapcache_cache_tc
403  */
404 mapcache_cache* mapcache_cache_tc_create(mapcache_context *ctx);
405 
406 /**
407  * \memberof mapcache_cache_riak
408  */
409 mapcache_cache* mapcache_cache_riak_create(mapcache_context *ctx);
410 
411 /** @} */
412 
413 
414 typedef enum {
415   MAPCACHE_REQUEST_UNKNOWN,
416   MAPCACHE_REQUEST_GET_TILE,
417   MAPCACHE_REQUEST_GET_MAP,
418   MAPCACHE_REQUEST_GET_CAPABILITIES,
419   MAPCACHE_REQUEST_GET_FEATUREINFO,
420   MAPCACHE_REQUEST_PROXY
421 } mapcache_request_type;
422 
423 typedef enum {
424   MAPCACHE_GETMAP_ERROR,
425   MAPCACHE_GETMAP_ASSEMBLE,
426   MAPCACHE_GETMAP_FORWARD
427 } mapcache_getmap_strategy;
428 
429 typedef enum {
430   MAPCACHE_RESAMPLE_NEAREST,
431   MAPCACHE_RESAMPLE_BILINEAR
432 } mapcache_resample_mode;
433 
434 /**
435  * \brief a request sent by a client
436  */
437 
438 struct mapcache_request {
439   mapcache_request_type type;
440   mapcache_service *service;
441 };
442 
443 struct mapcache_request_image {
444     mapcache_request request;
445     mapcache_image_format *format;
446 };
447 
448 struct mapcache_request_get_tile {
449   mapcache_request_image image_request;
450 
451   /**
452    * a list of tiles requested by the client
453    */
454   mapcache_tile **tiles;
455 
456   /**
457    * the number of tiles requested by the client.
458    * If more than one, and merging is enabled,
459    * the supplied tiles will be merged together
460    * before being returned to the client
461    */
462   int ntiles;
463   int allow_redirect;
464 };
465 
466 struct mapcache_http_response {
467   mapcache_buffer *data;
468   apr_table_t *headers;
469   long code;
470   apr_time_t mtime;
471 };
472 
473 struct mapcache_map {
474   mapcache_tileset *tileset;
475   mapcache_grid_link *grid_link;
476   apr_array_header_t *dimensions;
477   mapcache_buffer *encoded_data;
478   mapcache_image *raw_image;
479   int nodata; /**< \sa mapcache_tile::nodata */
480   int width, height;
481   mapcache_extent extent;
482   apr_time_t mtime; /**< last modification time */
483   int expires; /**< time in seconds after which the tile should be rechecked for validity */
484 };
485 
486 struct mapcache_feature_info {
487   mapcache_map map;
488   int i,j;
489   char *format;
490   mapcache_buffer *data;
491 };
492 
493 struct mapcache_request_get_feature_info {
494   mapcache_request request;
495   mapcache_feature_info *fi;
496 };
497 
498 struct mapcache_request_get_map {
499   mapcache_request_image image_request;
500   mapcache_map **maps;
501   int nmaps;
502   mapcache_getmap_strategy getmap_strategy;
503   mapcache_resample_mode resample_mode;
504 };
505 
506 struct mapcache_request_get_capabilities {
507   mapcache_request request;
508 
509   /**
510    * the body of the capabilities
511    */
512   char *capabilities;
513 
514   /**
515    * the mime type
516    */
517   char *mime_type;
518 };
519 
520 
521 
522 struct mapcache_forwarding_rule {
523   char *name;
524   mapcache_http *http;
525   apr_array_header_t *match_params;  /* actually those are mapcache_dimensions */
526   int append_pathinfo;
527   size_t max_post_len;
528 };
529 
530 struct mapcache_request_proxy {
531   mapcache_request request;
532   mapcache_forwarding_rule *rule;
533   apr_table_t *params;
534   apr_table_t *headers;
535   const char *pathinfo;
536   char *post_buf;
537   size_t post_len;
538 };
539 
540 
541 
542 
543 /** \defgroup services Services*/
544 /** @{ */
545 
546 #define MAPCACHE_SERVICES_COUNT 8
547 
548 typedef enum {
549   MAPCACHE_SERVICE_TMS=0, MAPCACHE_SERVICE_WMTS,
550   MAPCACHE_SERVICE_DEMO, MAPCACHE_SERVICE_GMAPS, MAPCACHE_SERVICE_KML,
551   MAPCACHE_SERVICE_VE, MAPCACHE_SERVICE_MAPGUIDE, MAPCACHE_SERVICE_WMS
552 } mapcache_service_type;
553 
554 #define MAPCACHE_UNITS_COUNT 3
555 typedef enum {
556   MAPCACHE_UNIT_METERS=0, MAPCACHE_UNIT_DEGREES, MAPCACHE_UNIT_FEET
557 } mapcache_unit;
558 
559 /* defined in util.c*/
560 extern const double mapcache_meters_per_unit[MAPCACHE_UNITS_COUNT];
561 
562 /** \interface mapcache_service
563  * \brief a standard service (eg WMS, TMS)
564  */
565 struct mapcache_service {
566   char *name;
567   mapcache_service_type type;
568 
569   /**
570    * the pathinfo prefix of the url that routes to this service
571    * eg, for accessing a wms service on http://host/mapcache/mywmsservice? ,
572    * url_prefix would take the value "mywmsservice"
573    */
574   char *url_prefix;
575 
576   /**
577    * \brief allocates and populates a mapcache_request corresponding to the parameters received
578    */
579   void (*parse_request)(mapcache_context *ctx, mapcache_service *service, mapcache_request **request, const char *path_info, apr_table_t *params, mapcache_cfg * config);
580 
581   /**
582    * \param request the received request (should be of type MAPCACHE_REQUEST_CAPABILITIES
583    * \param url the full url at which the service is available
584    */
585   void (*create_capabilities_response)(mapcache_context *ctx, mapcache_request_get_capabilities *request, char *url, char *path_info, mapcache_cfg *config);
586 
587   /**
588    * parse advanced configuration options for the selected service
589    */
590   void (*configuration_parse_xml)(mapcache_context *ctx, ezxml_t xml, mapcache_service * service, mapcache_cfg *config);
591 
592   void (*format_error)(mapcache_context *ctx, mapcache_service * service, char *err_msg,
593                        char **err_body, apr_table_t *headers);
594 };
595 
596 
597 
598 
599 
600 /**
601  * \brief create and initialize a mapcache_service_wms
602  * \memberof mapcache_service_wms
603  */
604 mapcache_service* mapcache_service_wms_create(mapcache_context *ctx);
605 
606 /**
607  * \brief create and initialize a mapcache_service_ve
608  * \memberof mapcache_service_ve
609  */
610 mapcache_service* mapcache_service_ve_create(mapcache_context *ctx);
611 
612 /**
613  * \brief create and initialize a mapcache_service_mapguide
614  * \memberof mapcache_service_mapguide
615  */
616 mapcache_service* mapcache_service_mapguide_create(mapcache_context *ctx);
617 
618 /**
619  * \brief create and initialize a mapcache_service_gmaps
620  * \memberof mapcache_service_gmaps
621  */
622 mapcache_service* mapcache_service_gmaps_create(mapcache_context *ctx);
623 
624 /**
625  * \brief create and initialize a mapcache_service_kml
626  * \memberof mapcache_service_kml
627  */
628 mapcache_service* mapcache_service_kml_create(mapcache_context *ctx);
629 
630 /**
631  * \brief create and initialize a mapcache_service_tms
632  * \memberof mapcache_service_tms
633  */
634 mapcache_service* mapcache_service_tms_create(mapcache_context *ctx);
635 
636 /**
637  * \brief create and initialize a mapcache_service_wmts
638  * \memberof mapcache_service_wtms
639  */
640 mapcache_service* mapcache_service_wmts_create(mapcache_context *ctx);
641 
642 /**
643  * \brief create and initialize a mapcache_service_demo
644  * \memberof mapcache_service_demo
645  */
646 mapcache_service* mapcache_service_demo_create(mapcache_context *ctx);
647 
648 /**
649  * \brief return the request that corresponds to the given url
650  */
651 MS_DLL_EXPORT void mapcache_service_dispatch_request(mapcache_context *ctx,
652                                        mapcache_request **request,
653                                        char *pathinfo,
654                                        apr_table_t *params,
655                                        mapcache_cfg *config);
656 /**
657  * \brief return the number of enabled/configured services
658  */
659 MS_DLL_EXPORT int mapcache_config_services_enabled(mapcache_context *ctx, mapcache_cfg *config);
660 
661 
662 /** @} */
663 
664 /** \defgroup image Image Data Handling */
665 
666 /** @{ */
667 
668 typedef enum {
669   GC_UNKNOWN, GC_PNG, GC_JPEG, GC_RAW
670 } mapcache_image_format_type;
671 
672 typedef enum {
673   MC_EMPTY_UNKNOWN, MC_EMPTY_YES, MC_EMPTY_NO
674 } mapcache_image_blank_type;
675 
676 typedef enum {
677   MC_ALPHA_UNKNOWN, MC_ALPHA_YES, MC_ALPHA_NO
678 } mapcache_image_alpha_type;
679 
680 
681 /**\class mapcache_image
682  * \brief representation of an RGBA image
683  *
684  * to access a pixel at position x,y, you should use the #GET_IMG_PIXEL macro
685  */
686 struct mapcache_image {
687   unsigned char *data; /**< pointer to the beginning of image data, stored in rgba order */
688   size_t w; /**< width of the image */
689   size_t h; /**< height of the image */
690   size_t stride; /**< stride of an image row */
691   mapcache_image_blank_type is_blank;
692   mapcache_image_alpha_type has_alpha;
693 
694 };
695 
696 /** \def GET_IMG_PIXEL
697  * return the address of a pixel
698  * \param y the row
699  * \param x the column
700  * \param img the mapcache_image
701  * \returns a pointer to the pixel
702  */
703 #define GET_IMG_PIXEL(img,x,y) (&((img).data[(y)*(img).stride + (x)*4]))
704 
705 
706 /**
707  * \brief initialize a new mapcache_image
708  */
709 mapcache_image* mapcache_image_create(mapcache_context *ctx);
710 mapcache_image* mapcache_image_create_with_data(mapcache_context *ctx, int width, int height);
711 
712 void mapcache_image_copy_resampled_nearest(mapcache_context *ctx, mapcache_image *src, mapcache_image *dst,
713     double off_x, double off_y, double scale_x, double scale_y);
714 void mapcache_image_copy_resampled_bilinear(mapcache_context *ctx, mapcache_image *src, mapcache_image *dst,
715     double off_x, double off_y, double scale_x, double scale_y, int reflect_edges);
716 
717 
718 /**
719  * \brief merge two images
720  * \param base the imae to merge onto
721  * \param overlay the image to overlay onto
722  * \param ctx the context
723  * when finished, base will be modified and have overlay merged onto it
724  */
725 void mapcache_image_merge(mapcache_context *ctx, mapcache_image *base, mapcache_image *overlay);
726 
727 void mapcache_image_copy_resampled(mapcache_context *ctx, mapcache_image *src, mapcache_image *dst,
728                                    int srcX, int srcY, int srcW, int srcH,
729                                    int dstX, int dstY, int dstW, int dstH);
730 
731 /**
732  * \brief split the given metatile into tiles
733  * \param mt the metatile to split
734  * \param r the context
735  */
736 void mapcache_image_metatile_split(mapcache_context *ctx, mapcache_metatile *mt);
737 
738 /**
739  * \brief check if given image is composed of a unique color
740  * \param image the mapcache_image to process
741  * \returns MAPCACHE_TRUE if the image contains a single color
742  * \returns MAPCACHE_FALSE if the image has more than one color
743  */
744 int mapcache_image_blank_color(mapcache_image* image);
745 
746 
747 /**
748  * \brief check if image has some non opaque pixels
749  */
750 int mapcache_image_has_alpha(mapcache_image *img, unsigned int cutoff);
751 
752 void mapcache_image_fill(mapcache_context *ctx, mapcache_image *image, const unsigned char *fill_color);
753 
754 /** @} */
755 
756 
757 /** \defgroup http HTTP Request handling*/
758 /** @{ */
759 void mapcache_http_do_request(mapcache_context *ctx, mapcache_http *req, mapcache_buffer *data, apr_table_t *headers, long *http_code);
760 char* mapcache_http_build_url(mapcache_context *ctx, char *base, apr_table_t *params);
761 MS_DLL_EXPORT apr_table_t *mapcache_http_parse_param_string(mapcache_context *ctx, char *args);
762 /** @} */
763 
764 /** \defgroup configuration Configuration*/
765 
766 /** @{ */
767 
768 
769 
770 
771 typedef enum {
772   MAPCACHE_MODE_NORMAL,
773   MAPCACHE_MODE_MIRROR_COMBINED,
774   MAPCACHE_MODE_MIRROR_SPLIT
775 } mapcache_mode;
776 
777 typedef enum {
778   MAPCACHE_LOCKER_DISK,
779   MAPCACHE_LOCKER_MEMCACHE,
780   MAPCACHE_LOCKER_FALLBACK
781 } mapcache_lock_mode;
782 
783 typedef enum {
784     MAPCACHE_LOCK_AQUIRED,
785     MAPCACHE_LOCK_LOCKED,
786     MAPCACHE_LOCK_NOENT
787 } mapcache_lock_result;
788 
789 
790 struct mapcache_locker{
791   mapcache_lock_result (*aquire_lock)(mapcache_context *ctx, mapcache_locker *self, char *resource, void **lock);
792   mapcache_lock_result (*ping_lock)(mapcache_context *ctx, mapcache_locker *self, void *lock);
793   void (*release_lock)(mapcache_context *ctx, mapcache_locker *self, void *lock);
794 
795   void (*parse_xml)(mapcache_context *ctx, mapcache_locker *self, ezxml_t node);
796   mapcache_lock_mode type;
797   double timeout;
798   double retry_interval; /* time to wait before checking again on a lock, in seconds */
799 };
800 
801 mapcache_locker* mapcache_locker_disk_create(mapcache_context *ctx);
802 
803 mapcache_locker* mapcache_locker_memcache_create(mapcache_context *ctx);
804 
805 mapcache_locker* mapcache_locker_fallback_create(mapcache_context *ctx);
806 
807 void mapcache_config_parse_locker(mapcache_context *ctx, ezxml_t node, mapcache_locker **locker);
808 void mapcache_config_parse_locker_old(mapcache_context *ctx, ezxml_t doc, mapcache_cfg *config);
809 
810 /**
811  * a configuration that will be served
812  */
813 struct mapcache_cfg {
814   /**
815    * a list of services that will be responded to
816    */
817   mapcache_service * services[MAPCACHE_SERVICES_COUNT];
818 
819   /**
820    * hashtable containing configured mapcache_source%s
821    */
822   apr_hash_t *sources;
823 
824   /**
825    * hashtable containing configured mapcache_cache%s
826    */
827   apr_hash_t *caches;
828 
829   /**
830    * hashtable containing configured mapcache_tileset%s
831    */
832   apr_hash_t *tilesets;
833 
834   /**
835    * hashtable containing configured mapcache_image_format%s
836    */
837   apr_hash_t *image_formats;
838 
839   /**
840    * hashtable containing (pre)defined grids
841    */
842   apr_hash_t *grids;
843 
844   /**
845    * hashtable containing (pre)defined rulesets
846    */
847   apr_hash_t *rulesets;
848 
849   /**
850    * the format to use for some miscelaneaous operations:
851    *  - creating an empty image
852    *  - creating an error image
853    *  - as a fallback when merging multiple tiles
854    */
855   mapcache_image_format *default_image_format;
856 
857   /**
858    * how should error messages be reported to the user
859    */
860   mapcache_error_reporting reporting;
861 
862   /**
863    * encoded empty (tranpsarent) image that will be returned to clients if cofigured
864    * to return blank images upon error
865    */
866   mapcache_buffer *empty_image;
867 
868   apr_table_t *metadata;
869 
870   mapcache_locker *locker;
871 
872   int threaded_fetching;
873 
874   /* for fastcgi only */
875   int autoreload; /* should the modification time of the config file be recorded
876                        and the file be reparsed if it is modified. */
877   mapcache_log_level loglevel; /* logging verbosity. Ignored for the apache module
878                                     as in that case the apache LogLevel directive is
879                                     used. */
880   mapcache_mode mode;
881 
882   /* return 404 on potentially blocking operations (proxying, source getmaps,
883    locks on metatile waiting, ... Used for nginx module */
884   int non_blocking;
885 
886   // Parameters for connection_pool:
887   // - cp_hmax defines the maximum number of open connections at the same time
888   // - cp_ttl defines the maximum amount of time in microseconds an unused connection is valid
889   int cp_hmax;
890   int cp_ttl;
891 };
892 
893 /**
894  *
895  * @param filename
896  * @param config
897  * @param pool
898  * @return
899  */
900 MS_DLL_EXPORT void mapcache_configuration_parse(mapcache_context *ctx, const char *filename, mapcache_cfg *config, int cgi);
901 MS_DLL_EXPORT void mapcache_configuration_post_config(mapcache_context *ctx, mapcache_cfg *config);
902 void mapcache_configuration_parse_xml(mapcache_context *ctx, const char *filename, mapcache_cfg *config);
903 MS_DLL_EXPORT mapcache_cfg* mapcache_configuration_create(apr_pool_t *pool);
904 mapcache_source* mapcache_configuration_get_source(mapcache_cfg *config, const char *key);
905 MS_DLL_EXPORT mapcache_cache* mapcache_configuration_get_cache(mapcache_cfg *config, const char *key);
906 mapcache_grid *mapcache_configuration_get_grid(mapcache_cfg *config, const char *key);
907 MS_DLL_EXPORT mapcache_tileset* mapcache_configuration_get_tileset(mapcache_cfg *config, const char *key);
908 mapcache_image_format *mapcache_configuration_get_image_format(mapcache_cfg *config, const char *key);
909 mapcache_ruleset *mapcache_configuration_get_ruleset(mapcache_cfg *config, const char *key);
910 void mapcache_configuration_add_image_format(mapcache_cfg *config, mapcache_image_format *format, const char * key);
911 void mapcache_configuration_add_source(mapcache_cfg *config, mapcache_source *source, const char * key);
912 void mapcache_configuration_add_grid(mapcache_cfg *config, mapcache_grid *grid, const char * key);
913 void mapcache_configuration_add_ruleset(mapcache_cfg *config, mapcache_ruleset *ruleset, const char * key);
914 void mapcache_configuration_add_tileset(mapcache_cfg *config, mapcache_tileset *tileset, const char * key);
915 void mapcache_configuration_add_cache(mapcache_cfg *config, mapcache_cache *cache, const char * key);
916 
917 /** @} */
918 /**
919  * \memberof mapcache_source
920  */
921 void mapcache_source_init(mapcache_context *ctx, mapcache_source *source);
922 
923 /**
924  * \memberof mapcache_source
925  */
926 void mapcache_source_render_map(mapcache_context *ctx, mapcache_source *source, mapcache_map *map);
927 void mapcache_source_query_info(mapcache_context *ctx, mapcache_source *source,
928     mapcache_feature_info *fi);
929 
930 /**
931  * \memberof mapcache_source_gdal
932  */
933 mapcache_source* mapcache_source_gdal_create(mapcache_context *ctx);
934 
935 /**
936  * \memberof mapcache_source_fallback
937  */
938 mapcache_source* mapcache_source_fallback_create(mapcache_context *ctx);
939 
940 /**
941  * \memberof mapcache_source_wms
942  */
943 mapcache_source* mapcache_source_wms_create(mapcache_context *ctx);
944 
945 /**
946  * \memberof mapcache_source_wms
947  */
948 mapcache_source* mapcache_source_mapserver_create(mapcache_context *ctx);
949 
950 mapcache_source* mapcache_source_dummy_create(mapcache_context *ctx);
951 
952 /**
953  * \memberof mapcache_cache_disk
954  */
955 mapcache_cache* mapcache_cache_disk_create(mapcache_context *ctx);
956 
957 /**
958  * \memberof mapcache_cache_rest
959  */
960 mapcache_cache* mapcache_cache_rest_create(mapcache_context *ctx);
961 mapcache_cache* mapcache_cache_s3_create(mapcache_context *ctx);
962 mapcache_cache* mapcache_cache_azure_create(mapcache_context *ctx);
963 mapcache_cache* mapcache_cache_google_create(mapcache_context *ctx);
964 
965 /**
966  * \memberof mapcache_cache_tiff
967  */
968 mapcache_cache* mapcache_cache_tiff_create(mapcache_context *ctx);
969 
970 mapcache_cache* mapcache_cache_composite_create(mapcache_context *ctx);
971 mapcache_cache* mapcache_cache_fallback_create(mapcache_context *ctx);
972 mapcache_cache* mapcache_cache_multitier_create(mapcache_context *ctx);
973 
974 
975 /** \defgroup tileset Tilesets*/
976 /** @{ */
977 
978 /**
979  * \brief Tile
980  * \sa mapcache_metatile
981  * \sa mapcache_tileset::metasize_x mapcache_tileset::metasize_x mapcache_tileset::metabuffer
982  */
983 struct mapcache_tile {
984   mapcache_tileset *tileset; /**< the mapcache_tileset that corresponds to the tile*/
985   mapcache_grid_link *grid_link;
986   int x; /**< tile x index */
987   int y; /**< tile y index */
988   int z; /**< tile z index (zoom level) */
989   /**
990    * encoded image data for the tile.
991    * \sa mapcache_cache::tile_get()
992    * \sa mapcache_source::render_map()
993    * \sa mapcache_image_format
994    */
995   mapcache_buffer *encoded_data;
996   char *redirect;
997   int allow_redirect;
998   mapcache_image *raw_image;
999   apr_time_t mtime; /**< last modification time */
1000   int expires; /**< time in seconds after which the tile should be rechecked for validity */
1001 
1002   apr_array_header_t *dimensions;
1003 
1004   /**
1005    * flag stating the tile is empty (i.e. fully transparent).
1006    * if set, this indicates that there was no error per se, but that there was
1007    * no way to get data back from the cache for this tile. This will happen for
1008    * a tileset with no <source> configured, for tiles that have not been preseeded.
1009    * Tile assembling functions should look for this flag and ignore such a tile when
1010    * compositing image data
1011    */
1012   int nodata;
1013 };
1014 
1015 /**
1016  * \brief  MetaTile
1017  * \extends mapcache_tile
1018  */
1019 struct mapcache_metatile {
1020   mapcache_map map;
1021   int x,y,z;
1022   int metasize_x, metasize_y;
1023   int ntiles; /**< the number of mapcache_metatile::tiles contained in this metatile */
1024   mapcache_tile *tiles; /**< the list of mapcache_tile s contained in this metatile */
1025 };
1026 
1027 
1028 struct mapcache_grid_level {
1029   double resolution;
1030   unsigned int maxx, maxy;
1031 };
1032 
1033 /**
1034  * \brief mapcache_grid_origin
1035  * determines at which extent extrema the tiles will originate from. Only
1036  * BOTTOM_LEFT and TOP_LEFT are implemented
1037  */
1038 typedef enum {
1039   MAPCACHE_GRID_ORIGIN_BOTTOM_LEFT,
1040   MAPCACHE_GRID_ORIGIN_TOP_LEFT,
1041   MAPCACHE_GRID_ORIGIN_BOTTOM_RIGHT,
1042   MAPCACHE_GRID_ORIGIN_TOP_RIGHT
1043 } mapcache_grid_origin;
1044 
1045 struct mapcache_grid {
1046   char *name;
1047   int nlevels;
1048   char *srs;
1049   apr_array_header_t *srs_aliases;
1050   mapcache_extent extent;
1051   mapcache_unit unit;
1052   int tile_sx, tile_sy; /**<width and height of a tile in pixels */
1053   mapcache_grid_level **levels;
1054   apr_table_t *metadata;
1055   mapcache_grid_origin origin;
1056 };
1057 
1058 typedef enum {
1059   MAPCACHE_OUTOFZOOM_NOTCONFIGURED = 0,
1060   MAPCACHE_OUTOFZOOM_REASSEMBLE,
1061   MAPCACHE_OUTOFZOOM_PROXY
1062 } mapcache_outofzoom_strategy;
1063 
1064 struct mapcache_grid_link {
1065   mapcache_grid *grid;
1066   /**
1067    * precalculated limits for available each level: [minTileX, minTileY, maxTileX, maxTileY].
1068    *
1069    * a request is valid if x is in [minTileX, maxTileX[ and y in [minTileY,maxTileY]
1070    */
1071   mapcache_extent *restricted_extent;
1072   mapcache_extent_i *grid_limits;
1073   int minz,maxz;
1074 
1075   /**
1076    * rules (mapcache_rule) for each zoom level
1077    * index in array = zoom level
1078    */
1079   apr_array_header_t *rules;
1080 
1081   /**
1082    * tiles above this zoom level will not be stored to the cache, but will be
1083    * dynamically generated (either by reconstructing from lower level tiles, or
1084    * by "proxying" the source
1085    */
1086 
1087   int max_cached_zoom;
1088   mapcache_outofzoom_strategy outofzoom_strategy;
1089 
1090   apr_array_header_t *intermediate_grids;
1091 };
1092 
1093 /**\class mapcache_rule
1094  * \brief a zoom level rule
1095  */
1096 struct mapcache_rule {
1097   /**
1098    * rule for zoom level
1099    */
1100   int zoom_level;
1101   /**
1102    * color of tiles when outside visible extent, ARGB
1103    */
1104   unsigned int hidden_color;
1105   /**
1106    * tile to return when outside visible extent
1107    */
1108   mapcache_buffer *hidden_tile;
1109   /**
1110    * visible extents, array of mapcache_extent
1111    */
1112   apr_array_header_t *visible_extents;
1113   /**
1114    * visible limits, array of mapcache_extent_i
1115    */
1116   apr_array_header_t *visible_limits;
1117 };
1118 
1119 /**\class mapcache_ruleset
1120  * \brief a set of rules
1121  */
1122 struct mapcache_ruleset {
1123   /**
1124    * the name of this ruleset
1125    */
1126   char *name;
1127   /**
1128    * rules (mapcache_rule)
1129    */
1130   apr_array_header_t *rules;
1131 };
1132 
1133 /**\class mapcache_tileset
1134  * \brief a set of tiles that can be requested by a client, created from a mapcache_source
1135  *        stored by a mapcache_cache in a mapcache_format
1136  */
1137 struct mapcache_tileset {
1138   /**
1139    * the name this tileset will be referenced by.
1140    * this is the key that is passed by clients e.g. in a WMS LAYERS= parameter
1141    */
1142   char *name;
1143 
1144   /**
1145    * the extent of the tileset in lonlat
1146    */
1147   mapcache_extent wgs84bbox;
1148 
1149   /**
1150    * list of grids that will be cached
1151    */
1152   apr_array_header_t *grid_links;
1153 
1154   /**
1155    * size of the metatile that should be requested to the mapcache_tileset::source
1156    */
1157   int metasize_x, metasize_y;
1158 
1159   /**
1160    * size of the gutter around the metatile that should be requested to the mapcache_tileset::source
1161    */
1162   int metabuffer;
1163 
1164   /**
1165    * number of seconds that should be returned to the client in an Expires: header
1166    *
1167    * \sa auto_expire
1168    */
1169   int expires;
1170 
1171   /**
1172    * number of seconds after which a tile will be regenerated from the source
1173    *
1174    * will take precedence over the #expires parameter.
1175    * \sa expires
1176    */
1177   int auto_expire;
1178 
1179   int read_only;
1180   int subdimension_read_only;
1181 
1182   /**
1183    * the cache in which the tiles should be stored
1184    */
1185   mapcache_cache *_cache;
1186 
1187   /**
1188    * the source from which tiles should be requested
1189    */
1190   mapcache_source *source;
1191 
1192   /**
1193    * the format to use when storing tiles coming from a metatile
1194    */
1195   mapcache_image_format *format;
1196 
1197   /**
1198    * a list of parameters that can be forwarded from the client to the mapcache_tileset::source
1199    */
1200   apr_array_header_t *dimensions;
1201 
1202   int store_dimension_assemblies;/**< should multiple sub-dimensions be assembled dynamically (per-request) or should they be cached once assembled */
1203 
1204   mapcache_dimension_assembly_type dimension_assembly_type;
1205 
1206   /**
1207    * Maximum zoom level for activating multithreaded subtile retrieval
1208    * -1 means 'not activated'
1209    */
1210   int assembly_threaded_fetching_maxzoom;
1211 
1212   /**
1213    * image to be used as a watermark
1214    */
1215   mapcache_image *watermark;
1216 
1217   /**
1218    * handle to the configuration this tileset belongs to
1219    */
1220   mapcache_cfg *config;
1221 
1222   apr_table_t *metadata;
1223 };
1224 
1225 
1226 mapcache_tileset* mapcache_tileset_clone(mapcache_context *ctx, mapcache_tileset *tileset);
1227 
1228 void mapcache_tileset_get_map_tiles(mapcache_context *ctx, mapcache_tileset *tileset,
1229                                     mapcache_grid_link *grid_link,
1230                                     mapcache_extent *bbox, int width, int height,
1231                                     int *ntiles,
1232                                     mapcache_tile ***tiles,
1233                                     mapcache_grid_link **effectively_used_grid_link,
1234                                     apr_array_header_t *dimensions);
1235 
1236 mapcache_image* mapcache_tileset_assemble_map_tiles(mapcache_context *ctx, mapcache_tileset *tileset,
1237     mapcache_grid_link *grid_link,
1238     mapcache_extent *bbox, int width, int height,
1239     int ntiles,
1240     mapcache_tile **tiles,
1241     mapcache_resample_mode mode);
1242 
1243 /**
1244  * compute x,y,z value given a bbox.
1245  * will return MAPCACHE_FAILURE
1246  * if the bbox does not correspond to the tileset's configuration
1247  */
1248 int mapcache_grid_get_cell(mapcache_context *ctx, mapcache_grid *grid, mapcache_extent *bbox,
1249                            int *x, int *y, int *z);
1250 
1251 /**
1252  * \brief verify the created tile respects configured constraints
1253  * @param tile
1254  * @param r
1255  * @return
1256  */
1257 void mapcache_tileset_tile_validate(mapcache_context *ctx, mapcache_tile *tile);
1258 void mapcache_tileset_tile_validate_z(mapcache_context *ctx, mapcache_tile *tile);
1259 void mapcache_tileset_tile_validate_x(mapcache_context *ctx, mapcache_tile *tile);
1260 void mapcache_tileset_tile_validate_y(mapcache_context *ctx, mapcache_tile *tile);
1261 
1262 /**
1263  * compute level for a given resolution
1264  *
1265  * computes the integer level for the given resolution. the input resolution will be set to the exact
1266  * value configured for the tileset, to compensate for rounding errors that could creep in if using
1267  * the resolution calculated from input parameters
1268  *
1269  * \returns MAPCACHE_TILESET_WRONG_RESOLUTION if the given resolution is't configured
1270  * \returns MAPCACHE_SUCCESS if the level was found
1271  */
1272 void mapcache_tileset_get_level(mapcache_context *ctx, mapcache_tileset *tileset, double *resolution, int *level);
1273 
1274 mapcache_grid_link* mapcache_grid_get_closest_wms_level(mapcache_context *ctx, mapcache_grid_link *grid, double resolution, int *level);
1275 MS_DLL_EXPORT void mapcache_tileset_tile_get(mapcache_context *ctx, mapcache_tile *tile);
1276 MS_DLL_EXPORT void mapcache_tileset_tile_set_get_with_subdimensions(mapcache_context *ctx, mapcache_tile *tile);
1277 
1278 /**
1279  * \brief delete tile from cache
1280  * @param whole_metatile delete all the other tiles from the metatile to
1281  */
1282 MS_DLL_EXPORT void mapcache_tileset_tile_delete(mapcache_context *ctx, mapcache_tile *tile, int whole_metatile);
1283 
1284 int mapcache_grid_is_bbox_aligned(mapcache_context *ctx, mapcache_grid *grid, mapcache_extent *bbox);
1285 
1286 /**
1287  * \brief create and initialize a tile for the given tileset and grid_link
1288  * @param tileset
1289  * @param grid_link
1290  * @param pool
1291  * @return
1292  */
1293 MS_DLL_EXPORT mapcache_tile* mapcache_tileset_tile_create(apr_pool_t *pool, mapcache_tileset *tileset, mapcache_grid_link *grid_link);
1294 
1295 mapcache_tile* mapcache_tileset_tile_clone(apr_pool_t *pool, mapcache_tile *src);
1296 
1297 /**
1298  * \brief create and initialize a map for the given tileset and grid_link
1299  * @param tileset
1300  * @param grid_link
1301  * @param pool
1302  * @return
1303  */
1304 mapcache_map* mapcache_tileset_map_create(apr_pool_t *pool, mapcache_tileset *tileset, mapcache_grid_link *grid_link);
1305 
1306 mapcache_map* mapcache_tileset_map_clone(apr_pool_t *pool, mapcache_map *src);
1307 
1308 
1309 /**
1310  * \brief create and initialize a feature_info for the given tileset and grid_link
1311  */
1312 mapcache_feature_info* mapcache_tileset_feature_info_create(apr_pool_t *pool, mapcache_tileset *tileset,
1313     mapcache_grid_link *grid_link);
1314 
1315 /**
1316  * \brief create and initalize a tileset
1317  * @param pool
1318  * @return
1319  */
1320 mapcache_tileset* mapcache_tileset_create(mapcache_context *ctx);
1321 
1322 void mapcache_tileset_configuration_check(mapcache_context *ctx, mapcache_tileset *tileset);
1323 void mapcache_tileset_add_watermark(mapcache_context *ctx, mapcache_tileset *tileset, const char *filename);
1324 
1325 
1326 MS_DLL_EXPORT int mapcache_lock_or_wait_for_resource(mapcache_context *ctx, mapcache_locker *locker, char *resource, void **lock);
1327 MS_DLL_EXPORT void mapcache_unlock_resource(mapcache_context *ctx, mapcache_locker *locker, void *lock);
1328 
1329 MS_DLL_EXPORT mapcache_metatile* mapcache_tileset_metatile_get(mapcache_context *ctx, mapcache_tile *tile);
1330 MS_DLL_EXPORT void mapcache_tileset_render_metatile(mapcache_context *ctx, mapcache_metatile *mt);
1331 MS_DLL_EXPORT char* mapcache_tileset_metatile_resource_key(mapcache_context *ctx, mapcache_metatile *mt);
1332 
1333 
1334 /** @} */
1335 
1336 
1337 
1338 MS_DLL_EXPORT mapcache_http_response* mapcache_core_get_capabilities(mapcache_context *ctx, mapcache_service *service, mapcache_request_get_capabilities *req_caps, char *url, char *path_info, mapcache_cfg *config);
1339 MS_DLL_EXPORT mapcache_http_response* mapcache_core_get_tile(mapcache_context *ctx, mapcache_request_get_tile *req_tile);
1340 
1341 MS_DLL_EXPORT mapcache_http_response* mapcache_core_get_map(mapcache_context *ctx, mapcache_request_get_map *req_map);
1342 
1343 MS_DLL_EXPORT mapcache_http_response* mapcache_core_get_featureinfo(mapcache_context *ctx, mapcache_request_get_feature_info *req_fi);
1344 
1345 MS_DLL_EXPORT mapcache_http_response* mapcache_core_proxy_request(mapcache_context *ctx, mapcache_request_proxy *req_proxy);
1346 MS_DLL_EXPORT mapcache_http_response* mapcache_core_respond_to_error(mapcache_context *ctx);
1347 
1348 
1349 /* in ruleset.c */
1350 
1351 /**
1352  * \brief allocate and initialize a new ruleset
1353  * @param pool
1354  */
1355 mapcache_ruleset* mapcache_ruleset_create(apr_pool_t *pool);
1356 
1357 /**
1358  * \brief allocate and initialize a new rule
1359  * @param pool
1360  */
1361 mapcache_rule* mapcache_ruleset_rule_create(apr_pool_t *pool);
1362 
1363 /**
1364  * \brief clone a rule
1365  * @param pool
1366  * @param rule
1367  */
1368 mapcache_rule* mapcache_ruleset_rule_clone(apr_pool_t *pool, mapcache_rule *rule);
1369 
1370 /**
1371  * \brief get rule for zoom level, or NULL if none exist
1372  * @param ruleset
1373  * @param zoom_level
1374  */
1375 mapcache_rule* mapcache_ruleset_rule_find(apr_array_header_t *rules, int zoom_level);
1376 
1377 /**
1378  * \brief get rule at index, or NULL if none exist
1379  * @param rules
1380  * @param idx
1381  */
1382 mapcache_rule* mapcache_ruleset_rule_get(apr_array_header_t *rules, int idx);
1383 
1384 /**
1385  * \brief check if tile is within visible extent
1386  * @param rule
1387  * @param tile
1388  */
1389 int mapcache_ruleset_is_visible_tile(mapcache_rule* rule, mapcache_tile *tile);
1390 
1391 
1392 /* in grid.c */
1393 mapcache_grid* mapcache_grid_create(apr_pool_t *pool);
1394 
1395 const char* mapcache_grid_get_crs(mapcache_context *ctx, mapcache_grid *grid);
1396 const char* mapcache_grid_get_srs(mapcache_context *ctx, mapcache_grid *grid);
1397 
1398 MS_DLL_EXPORT void mapcache_grid_get_tile_extent(mapcache_context *ctx, mapcache_grid *grid,
1399                               int x, int y, int z, mapcache_extent *bbox);
1400 
1401 MS_DLL_EXPORT void mapcache_grid_get_metatile_extent(mapcache_context *ctx, mapcache_tile *tile, mapcache_extent *bbox);
1402 
1403 /**
1404  * \brief compute x y value for given lon/lat (dx/dy) and given zoomlevel
1405  * @param ctx
1406  * @param tileset
1407  * @param dx
1408  * @param dy
1409  * @param z
1410  * @param x
1411  * @param y
1412  */
1413 MS_DLL_EXPORT void mapcache_grid_get_xy(mapcache_context *ctx, mapcache_grid *grid, double dx, double dy, int z, int *x, int *y);
1414 
1415 double mapcache_grid_get_resolution(mapcache_extent *bbox, int sx, int sy);
1416 double mapcache_grid_get_horizontal_resolution(mapcache_extent *bbox, int width);
1417 double mapcache_grid_get_vertical_resolution(mapcache_extent *bbox, int height);
1418 
1419 /**
1420  * \brief compute grid level given a resolution
1421  * \param grid
1422  * \param resolution
1423  * \param level
1424  */
1425 int mapcache_grid_get_level(mapcache_context *ctx, mapcache_grid *grid, double *resolution, int *level);
1426 
1427 /**
1428  * \brief precompute min/max x/y values for the given extent
1429  * \param grid
1430  * \param extent
1431  * \param tolerance the number of tiles around the given extent that can be requested without returning an error.
1432  */
1433 MS_DLL_EXPORT void mapcache_grid_compute_limits(const mapcache_grid *grid, const mapcache_extent *extent, mapcache_extent_i *limits, int tolerance);
1434 void mapcache_grid_compute_limits_at_level(const mapcache_grid *grid, const mapcache_extent *extent, mapcache_extent_i *limits_ptr, int tolerance, int zoom_level);
1435 
1436 /* in util.c */
1437 MS_DLL_EXPORT int mapcache_util_extract_int_list(mapcache_context *ctx, const char* args, const char *sep, int **numbers,
1438                                    int *numbers_count);
1439 MS_DLL_EXPORT int mapcache_util_extract_double_list(mapcache_context *ctx, const char* args, const char *sep, double **numbers,
1440                                       int *numbers_count);
1441 MS_DLL_EXPORT char *mapcache_util_str_replace(apr_pool_t *pool, const char *string, const char *substr,
1442                                 const char *replacement );
1443 char *mapcache_util_dbl_replace(apr_pool_t *pool, const char *string, const char *substr,
1444                                 double replacement );
1445 char *mapcache_util_str_replace_all(apr_pool_t *pool, const char *string, const char *substr,
1446                                     const char *replacement );
1447 char *mapcache_util_dbl_replace_all(apr_pool_t *pool, const char *string, const char *substr,
1448                                     double replacement );
1449 void mapcache_util_quadkey_decode(mapcache_context *ctx, const char *quadkey, int *x, int *y, int *z);
1450 
1451 char* mapcache_util_quadkey_encode(mapcache_context *ctx, int x, int y, int z);
1452 
1453 /**
1454  * \brief replace dangerous characters in string
1455  * \param str the string that must be tested/replaced
1456  * \param from array of chars that must be replaced
1457  * \param to char that will replace a matched entry
1458  * \return the original string if no matches were found, or the sanitized
1459  *         string allocated from the given pool
1460  */
1461 MS_DLL_EXPORT char* mapcache_util_str_sanitize(apr_pool_t *pool, const char *str, const char* from, char to);
1462 
1463 typedef enum {
1464   MAPCACHE_UTIL_XML_SECTION_TEXT,
1465   MAPCACHE_UTIL_XML_SECTION_ATTRIBUTE,
1466   MAPCACHE_UTIL_XML_SECTION_COMMENT
1467 } mapcache_util_xml_section_type;
1468 
1469 char* mapcache_util_str_xml_escape(apr_pool_t *pool, const char *str, mapcache_util_xml_section_type xml_section_type);
1470 
1471 MS_DLL_EXPORT char* mapcache_util_get_tile_dimkey(mapcache_context *ctx, mapcache_tile *tile, char* sanitized_chars, char *sanitize_to);
1472 
1473 char* mapcache_util_get_tile_key(mapcache_context *ctx, mapcache_tile *tile, char *stemplate,
1474                                  char* sanitized_chars, char *sanitize_to);
1475 void mapcache_make_parent_dirs(mapcache_context *ctx, char *filename);
1476 
1477 /**\defgroup imageio Image IO */
1478 /** @{ */
1479 
1480 /**
1481  * compression strategy to apply
1482  */
1483 typedef enum {
1484   MAPCACHE_COMPRESSION_BEST, /**< best but slowest compression*/
1485   MAPCACHE_COMPRESSION_FAST, /**< fast compression*/
1486   MAPCACHE_COMPRESSION_DISABLE, /**< no compression*/
1487   MAPCACHE_COMPRESSION_DEFAULT /**< default compression*/
1488 } mapcache_compression_type;
1489 
1490 /**
1491  * photometric interpretation for jpeg bands
1492  */
1493 typedef enum {
1494   MAPCACHE_PHOTOMETRIC_RGB,
1495   MAPCACHE_PHOTOMETRIC_YCBCR
1496 } mapcache_photometric;
1497 
1498 /**
1499  * optimization settings (mostly) for jpeg
1500  */
1501 typedef enum {
1502   MAPCACHE_OPTIMIZE_NO,
1503   MAPCACHE_OPTIMIZE_YES,
1504   MAPCACHE_OPTIMIZE_ARITHMETIC
1505 } mapcache_optimization;
1506 
1507 /**\interface mapcache_image_format
1508  * \brief an image format
1509  * \sa mapcache_image_format_jpeg
1510  * \sa mapcache_image_format_png
1511  */
1512 struct mapcache_image_format {
1513   char *name; /**< the key by which this format will be referenced */
1514   char *extension; /**< the extension to use when saving a file with this format */
1515   char *mime_type;
1516   mapcache_buffer * (*write)(mapcache_context *ctx, mapcache_image *image, mapcache_image_format * format);
1517   /**< pointer to a function that returns a mapcache_buffer containing the given image encoded
1518    * in the specified format
1519    */
1520 
1521   mapcache_buffer* (*create_empty_image)(mapcache_context *ctx, mapcache_image_format *format,
1522                                          size_t width, size_t height, unsigned int color);
1523   apr_table_t *metadata;
1524   mapcache_image_format_type type;
1525 };
1526 
1527 /**\defgroup imageio_png PNG Image IO
1528  * \ingroup imageio */
1529 /** @{ */
1530 
1531 /**\class mapcache_image_format_png
1532  * \brief PNG image format
1533  * \extends mapcache_image_format
1534  * \sa mapcache_image_format_png_q
1535  */
1536 struct mapcache_image_format_png {
1537   mapcache_image_format format;
1538   mapcache_compression_type compression_level; /**< PNG compression level to apply */
1539 };
1540 
1541 struct mapcache_image_format_mixed {
1542   mapcache_image_format format;
1543   mapcache_image_format *transparent;
1544   mapcache_image_format *opaque;
1545   unsigned int alpha_cutoff; /* default 255. pixels with alpha >= alpha_cutoff will be considered fully opaque */
1546 };
1547 
1548 mapcache_buffer* mapcache_empty_png_decode(mapcache_context *ctx, int width, int height, const unsigned char *hex_color, int *is_empty);
1549 
1550 mapcache_image_format* mapcache_imageio_create_mixed_format(apr_pool_t *pool,
1551     char *name, mapcache_image_format *transparent, mapcache_image_format *opaque, unsigned int alpha_cutoff);
1552 
1553 struct mapcache_image_format_raw {
1554   mapcache_image_format format;
1555 };
1556 
1557 mapcache_image_format* mapcache_imageio_create_raw_format(apr_pool_t *pool, char *name, char *extension, char *mime_type);
1558 int mapcache_imageio_is_raw_tileset(mapcache_tileset *tileset);
1559 
1560 /**\class mapcache_image_format_png_q
1561  * \brief Quantized PNG format
1562  * \extends mapcache_image_format_png
1563  */
1564 struct mapcache_image_format_png_q {
1565   mapcache_image_format_png format;
1566   int ncolors; /**< number of colors used in quantization, 2-256 */
1567 };
1568 
1569 /**
1570  * @param r
1571  * @param buffer
1572  * @return
1573  */
1574 mapcache_image* _mapcache_imageio_png_decode(mapcache_context *ctx, mapcache_buffer *buffer);
1575 
1576 void mapcache_image_create_empty(mapcache_context *ctx, mapcache_cfg *cfg);
1577 /**
1578  * @param r
1579  * @param buffer
1580  * @return
1581  */
1582 void _mapcache_imageio_png_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer,
1583     mapcache_image *image);
1584 
1585 
1586 /**
1587  * \brief create a format capable of creating RGBA png
1588  * \memberof mapcache_image_format_png
1589  * @param pool
1590  * @param name
1591  * @param compression the ZLIB compression to apply
1592  * @return
1593  */
1594 mapcache_image_format* mapcache_imageio_create_png_format(apr_pool_t *pool, char *name, mapcache_compression_type compression);
1595 
1596 /**
1597  * \brief create a format capable of creating quantized png
1598  * \memberof mapcache_image_format_png_q
1599  * @param pool
1600  * @param name
1601  * @param compression the ZLIB compression to apply
1602  * @param ncolors the number of colors to quantize with
1603  * @return
1604  */
1605 mapcache_image_format* mapcache_imageio_create_png_q_format(apr_pool_t *pool, char *name, mapcache_compression_type compression, int ncolors);
1606 
1607 /** @} */
1608 
1609 /**\defgroup imageio_jpg JPEG Image IO
1610  * \ingroup imageio */
1611 /** @{ */
1612 
1613 /**\class mapcache_image_format_jpeg
1614  * \brief JPEG image format
1615  * \extends mapcache_image_format
1616  */
1617 struct mapcache_image_format_jpeg {
1618   mapcache_image_format format;
1619   int quality; /**< JPEG quality, 1-100 */
1620   mapcache_photometric photometric;
1621   mapcache_optimization optimize;
1622 };
1623 
1624 mapcache_image_format* mapcache_imageio_create_jpeg_format(apr_pool_t *pool, char *name, int quality,
1625     mapcache_photometric photometric, mapcache_optimization optimize);
1626 
1627 /**
1628  * @param r
1629  * @param buffer
1630  * @return
1631  */
1632 mapcache_image* _mapcache_imageio_jpeg_decode(mapcache_context *ctx, mapcache_buffer *buffer);
1633 
1634 /**
1635  * @param r
1636  * @param buffer
1637  * @return
1638  */
1639 void _mapcache_imageio_jpeg_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer,
1640     mapcache_image *image);
1641 
1642 /** @} */
1643 
1644 /**
1645  * \brief lookup the first few bytes of a buffer to check for a known image format
1646  */
1647 mapcache_image_format_type mapcache_imageio_header_sniff(mapcache_context *ctx, mapcache_buffer *buffer);
1648 
1649 /**
1650  * \brief lookup the first few bytes of a buffer to check for alpha channel
1651  */
1652 mapcache_image_alpha_type mapcache_imageio_alpha_sniff(mapcache_context *ctx, mapcache_buffer *buffer);
1653 
1654 /**
1655  * \brief checks if the given buffer is a recognized image format
1656  */
1657 int mapcache_imageio_is_valid_format(mapcache_context *ctx, mapcache_buffer *buffer);
1658 
1659 
1660 /**
1661  * decodes given buffer
1662  */
1663 mapcache_image* mapcache_imageio_decode(mapcache_context *ctx, mapcache_buffer *buffer);
1664 
1665 /**
1666  * decodes given buffer to an allocated image
1667  */
1668 void mapcache_imageio_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer, mapcache_image *image);
1669 
1670 
1671 /** @} */
1672 
1673 typedef struct {
1674   double start;
1675   double end;
1676   double resolution;
1677 } mapcache_interval;
1678 
1679 struct mapcache_requested_dimension {
1680   mapcache_dimension *dimension;
1681   char *requested_value;
1682   char *cached_value;
1683   apr_array_header_t *cached_entries_for_value;
1684 };
1685 
1686 void mapcache_tile_set_cached_dimension(mapcache_context *ctx, mapcache_tile *tile, const char *name, const char *value);
1687 void mapcache_map_set_cached_dimension(mapcache_context *ctx, mapcache_map *map, const char *name, const char *value);
1688 void mapcache_tile_set_requested_dimension(mapcache_context *ctx, mapcache_tile *tile, const char *name, const char *value);
1689 void mapcache_map_set_requested_dimension(mapcache_context *ctx, mapcache_map *map, const char *name, const char *value);
1690 MS_DLL_EXPORT void mapcache_set_requested_dimension(mapcache_context *ctx, apr_array_header_t *dimensions, const char *name, const char *value);
1691 MS_DLL_EXPORT void mapcache_set_cached_dimension(mapcache_context *ctx, apr_array_header_t *dimensions, const char *name, const char *value);
1692 MS_DLL_EXPORT apr_array_header_t *mapcache_requested_dimensions_clone(apr_pool_t *pool, apr_array_header_t *src);
1693 
1694 struct mapcache_dimension {
1695   mapcache_dimension_type type;
1696   const char *class_name;
1697   int isTime;
1698   int wms_querybymap_minzoom;
1699   char *name;
1700   char *unit;
1701   apr_table_t *metadata;
1702   char *default_value;
1703 
1704   /**
1705    * \brief return the list of dimension values that match the requested entry
1706    */
1707   apr_array_header_t* (*_get_entries_for_value)(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
1708                        mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
1709 
1710   /**
1711    * \brief return the list of dimension values that match the requested time range
1712    */
1713   apr_array_header_t* (*_get_entries_for_time_range)(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
1714                        time_t start, time_t end,
1715                        mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
1716 
1717   /**
1718    * \brief return all possible values
1719    */
1720   apr_array_header_t* (*get_all_entries)(mapcache_context *ctx, mapcache_dimension *dimension,
1721                        mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
1722 
1723   /**
1724    * \brief return all possible values formatted in a way compatible with OGC capabilities <dimension> element
1725    */
1726   apr_array_header_t* (*get_all_ogc_formatted_entries)(mapcache_context *ctx, mapcache_dimension *dimension,
1727                        mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
1728 
1729   /**
1730    * \brief parse the value given in the configuration
1731    */
1732   void (*configuration_parse_xml)(mapcache_context *context, mapcache_dimension *dim, ezxml_t node);
1733 };
1734 
1735 mapcache_dimension* mapcache_dimension_values_create(mapcache_context *ctx, apr_pool_t *pool);
1736 mapcache_dimension* mapcache_dimension_sqlite_create(mapcache_context *ctx, apr_pool_t *pool);
1737 mapcache_dimension* mapcache_dimension_postgresql_create(mapcache_context *ctx, apr_pool_t *pool);
1738 mapcache_dimension* mapcache_dimension_regex_create(mapcache_context *ctx, apr_pool_t *pool);
1739 mapcache_dimension* mapcache_dimension_time_create(mapcache_context *ctx, apr_pool_t *pool);
1740 mapcache_dimension* mapcache_dimension_elasticsearch_create(mapcache_context *ctx, apr_pool_t *pool);
1741 
1742 MS_DLL_EXPORT apr_array_header_t* mapcache_dimension_get_entries_for_value(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
1743                        mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
1744 apr_array_header_t* mapcache_dimension_time_get_entries_for_value(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
1745                        mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
1746 
1747 int mapcache_is_axis_inverted(const char *srs);
1748 
1749 typedef struct mapcache_pooled_connection_container mapcache_pooled_connection_container;
1750 typedef struct mapcache_pooled_connection mapcache_pooled_connection;
1751 typedef struct mapcache_pooled_connection_private_data mapcache_pooled_connection_private_data;
1752 
1753 struct mapcache_pooled_connection {
1754     mapcache_pooled_connection_private_data *private;
1755     void *connection;
1756 };
1757 
1758 typedef void (*mapcache_connection_constructor)(mapcache_context *ctx, void **connection, void *params);
1759 typedef void (*mapcache_connection_destructor)(void *connection);
1760 
1761 MS_DLL_EXPORT apr_status_t mapcache_connection_pool_create(mapcache_cfg *cfg, mapcache_connection_pool **cp, apr_pool_t *server_pool);
1762 mapcache_pooled_connection* mapcache_connection_pool_get_connection(mapcache_context *ctx, char *key,
1763         mapcache_connection_constructor constructor,
1764         mapcache_connection_destructor destructor,
1765         void *params);
1766 void mapcache_connection_pool_invalidate_connection(mapcache_context *ctx, mapcache_pooled_connection *connection);
1767 void mapcache_connection_pool_release_connection(mapcache_context *ctx, mapcache_pooled_connection *connection);
1768 
1769 #endif /* MAPCACHE_H_ */
1770 /* vim: ts=2 sts=2 et sw=2
1771 */
1772