1 /******************************************************************************
2  * $Id$
3  *
4  * Project:  MapServer
5  * Purpose:  MapCache ruleset support file
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 
32 /*
33  * allocate and initialize a new ruleset
34  */
mapcache_ruleset_create(apr_pool_t * pool)35 mapcache_ruleset* mapcache_ruleset_create(apr_pool_t *pool)
36 {
37   mapcache_ruleset* ruleset = (mapcache_ruleset*)apr_pcalloc(pool, sizeof(mapcache_ruleset));
38   ruleset->rules = apr_array_make(pool,0,sizeof(mapcache_rule*));
39   return ruleset;
40 }
41 
42 /*
43  * allocate and initialize a new rule
44  */
mapcache_ruleset_rule_create(apr_pool_t * pool)45 mapcache_rule* mapcache_ruleset_rule_create(apr_pool_t *pool)
46 {
47   mapcache_rule* rule = (mapcache_rule*)apr_pcalloc(pool, sizeof(mapcache_rule));
48   rule->zoom_level = -1;
49   rule->visible_extents = apr_array_make(pool,0,sizeof(mapcache_extent*));
50   rule->visible_limits = apr_array_make(pool,0,sizeof(mapcache_extent_i*));
51   rule->hidden_color = 0x00ffffff; // default is white with full transparency
52   rule->hidden_tile = NULL;
53   return rule;
54 }
55 
56 /*
57  * clone a rule
58  */
mapcache_ruleset_rule_clone(apr_pool_t * pool,mapcache_rule * rule)59 mapcache_rule* mapcache_ruleset_rule_clone(apr_pool_t *pool, mapcache_rule *rule)
60 {
61   mapcache_rule* clone = mapcache_ruleset_rule_create(pool);
62 
63   clone->zoom_level = rule->zoom_level;
64   clone->hidden_color = rule->hidden_color;
65   clone->hidden_tile = rule->hidden_tile; //no need to copy, just point to same buffer/tile.
66 
67   if(rule->visible_extents) {
68     int i;
69     for(i = 0; i < rule->visible_extents->nelts; i++) {
70       mapcache_extent *extent_clone = (mapcache_extent*)apr_pcalloc(pool, sizeof(mapcache_extent));
71       mapcache_extent *extent = APR_ARRAY_IDX(rule->visible_extents, i, mapcache_extent*);
72       *extent_clone = *extent;
73       APR_ARRAY_PUSH(clone->visible_extents, mapcache_extent*) = extent_clone;
74     }
75   }
76 
77   if(rule->visible_limits) {
78     int i;
79     for(i = 0; i < rule->visible_limits->nelts; i++) {
80       mapcache_extent_i *extent_clone = (mapcache_extent_i*)apr_pcalloc(pool, sizeof(mapcache_extent_i));
81       mapcache_extent_i *extent = APR_ARRAY_IDX(rule->visible_limits, i, mapcache_extent_i*);
82       *extent_clone = *extent;
83       APR_ARRAY_PUSH(clone->visible_limits, mapcache_extent_i*) = extent_clone;
84     }
85   }
86 
87   return clone;
88 }
89 
90 /*
91  * find rule for zoom level, or NULL if none exist
92  */
mapcache_ruleset_rule_find(apr_array_header_t * rules,int zoom_level)93 mapcache_rule* mapcache_ruleset_rule_find(apr_array_header_t *rules, int zoom_level)
94 {
95   int i;
96   mapcache_rule* rule;
97 
98   if (!rules) {
99     return NULL;
100   }
101 
102   for(i = 0; i < rules->nelts; i++) {
103     if ((rule = APR_ARRAY_IDX(rules, i, mapcache_rule*))->zoom_level == zoom_level) {
104       return rule;
105     }
106   }
107   return NULL;
108 }
109 
110 /*
111  * get rule at index, or NULL if index is out of bounds.
112  */
mapcache_ruleset_rule_get(apr_array_header_t * rules,int idx)113 mapcache_rule* mapcache_ruleset_rule_get(apr_array_header_t *rules, int idx)
114 {
115   mapcache_rule *rule;
116 
117   if(!rules || idx < 0 || idx >= rules->nelts) {
118     return NULL;
119   }
120 
121   rule = APR_ARRAY_IDX(rules, idx, mapcache_rule*);
122   return rule;
123 }
124 
125 /*
126  * check if tile is within visible limits
127  */
mapcache_ruleset_is_visible_tile(mapcache_rule * rule,mapcache_tile * tile)128 int mapcache_ruleset_is_visible_tile(mapcache_rule* rule, mapcache_tile *tile) {
129   int i;
130 
131   if(!rule || !rule->visible_limits || apr_is_empty_array(rule->visible_limits)) {
132     return MAPCACHE_TRUE;
133   }
134 
135   for(i = 0; i < rule->visible_limits->nelts; i++) {
136     mapcache_extent_i *extent = APR_ARRAY_IDX(rule->visible_limits, i, mapcache_extent_i*);
137 
138     if(tile->x >= extent->minx && tile->y >= extent->miny &&
139        tile->x <= extent->maxx && tile->y <= extent->maxy) {
140       return MAPCACHE_TRUE;
141     }
142   }
143 
144   return MAPCACHE_FALSE;
145 }
146