tinyows 1.2.2
ows_geobbox.c
Go to the documentation of this file.
1/*
2 Copyright (c) <2007-2012> <Barbara Philippot - Olivier Courtin>
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 IN THE SOFTWARE.
21*/
22
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <assert.h>
27#include <float.h>
28#include <math.h>
29#include <string.h>
30
31#include "ows.h"
32
33
34/*
35 * Initialize a geobbox structure
36 */
38{
39 ows_geobbox *g;
40
41 g = malloc(sizeof(ows_geobbox));
42 assert(g != NULL);
43
44 g->west = DBL_MIN;
45 g->east = DBL_MIN;
46 g->south = DBL_MIN;
47 g->north = DBL_MIN;
48
49 return g;
50}
51
52
53/*
54 * Clone a geobbox
55 */
57{
58 ows_geobbox *c;
59
60 assert(g);
61 c = malloc(sizeof(*g));
62 return memcpy(c, g, sizeof(*g));
63}
64
65
66/*
67 * Free a geobbox structure
68 */
70{
71 assert(g);
72 free(g);
73 g = NULL;
74}
75
76
77/*
78 * Set a given geobbox with null area and earth limits tests
79 */
80bool ows_geobbox_set(ows * o, ows_geobbox * g, double west, double east, double south, double north)
81{
82 double geom_tolerance = 0.01;
83
84 assert(g);
85
86 if (south + geom_tolerance < -90.0 || south - geom_tolerance > 90.0 ||
87 north + geom_tolerance < -90.0 || north - geom_tolerance > 90.0 ||
88 east + geom_tolerance < -180.0 || east - geom_tolerance > 180.0 ||
89 west + geom_tolerance < -180.0 || west - geom_tolerance > 180.0)
90 return false;
91
92 if (fabs(south - north) < DBL_EPSILON || fabs(east - west) < DBL_EPSILON)
93 return false;
94
95 /* TODO add a test to see if north is northern than south and so forth... */
96 g->west = west;
97 g->east = east;
98 g->south = south;
99 g->north = north;
100
101 return true;
102}
103
104
105/*
106 * Set a given geobbox from a bbox
107 */
109{
110 double west, east, south, north;
111
112 assert(g);
113 assert(bb);
114
115 if (bb->ymin < 0.0 && bb->ymax < 0.0) {
116 south = bb->ymax;
117 north = bb->ymin;
118 west = bb->xmax;
119 east = bb->xmin;
120 } else {
121 south = bb->ymin;
122 north = bb->ymax;
123 west = bb->xmin;
124 east = bb->xmax;
125 }
126
127 return ows_geobbox_set(o, g, west, east, south, north);
128}
129
130
131/*
132 * Set a given geobbox from a string like 'xmin,ymin,xmax,ymax'
133 */
135{
136 ows_bbox *bb;
137
138 assert(g);
139 assert(str);
140
141 bb = ows_bbox_init();
142 ows_bbox_set_from_str(o, bb, str, 4326, false);
144 ows_bbox_free(bb);
145
146 return g;
147}
148
149
150/*
151 * Set a geobbox matching a layer's extent
152 */
154{
155 double xmin, ymin, xmax, ymax;
156 buffer *sql;
157 PGresult *res;
158 ows_geobbox *g;
159 ows_bbox *bb;
160 const list *geom;
161 const list_node *ln;
162 bool first = true;
163
164 assert(o);
165 assert(layer_name);
166
167 geom = ows_psql_geometry_column(o, layer_name);
168 if( geom->first == NULL )
169 return NULL;
170
171 sql = buffer_init();
172
173 g = ows_geobbox_init();
174 xmin = ymin = xmax = ymax = 0.0;
175
176 for (ln = geom->first; ln ; ln = ln->next) {
177 buffer_add_str(sql, "SELECT ST_xmin(g), ST_ymin(g), ST_xmax(g), ST_ymax(g) FROM ");
178 if (o->estimated_extent) {
179 buffer_add_str(sql, "(SELECT ST_Transform(ST_SetSRID(ST_Estimated_Extent('");
180 buffer_copy(sql, ows_psql_schema_name(o, layer_name));
181 buffer_add_str(sql, "','");
182 buffer_copy(sql, ows_psql_table_name(o, layer_name));
183 buffer_add_str(sql, "','");
184 buffer_copy(sql, ln->value);
185 buffer_add_str(sql, "'), (SELECT ST_SRID(\"");
186 buffer_copy(sql, ln->value);
187 buffer_add_str(sql, "\") FROM \"");
188 buffer_copy(sql, ows_psql_schema_name(o, layer_name));
189 buffer_add_str(sql, "\".\"");
190 buffer_copy(sql, ows_psql_table_name(o, layer_name));
191 buffer_add_str(sql, "\" LIMIT 1)) ,4326) AS g) AS foo");
192 } else {
193 buffer_add_str(sql, "(SELECT ST_Transform(ST_SetSRID(ST_Extent(\"");
194 buffer_copy(sql, ln->value);
195 buffer_add_str(sql, "\"), (SELECT ST_SRID(\"");
196 buffer_copy(sql, ln->value);
197 buffer_add_str(sql, "\") FROM \"");
198 buffer_copy(sql, ows_psql_schema_name(o, layer_name));
199 buffer_add_str(sql, "\".\"");
200 buffer_copy(sql, ows_psql_table_name(o, layer_name));
201 buffer_add_str(sql, "\" LIMIT 1)), 4326) AS g ");
202 buffer_add_str(sql, " FROM \"");
203 buffer_copy(sql, ows_psql_schema_name(o, layer_name));
204 buffer_add_str(sql, "\".\"");
205 buffer_copy(sql, ows_psql_table_name(o, layer_name));
206 buffer_add_str(sql, "\" ) AS foo");
207 }
208
209 res = ows_psql_exec(o, sql->buf);
210 buffer_empty(sql);
211 if (PQresultStatus(res) != PGRES_TUPLES_OK) {
212 PQclear(res);
213 buffer_free(sql);
214 return g;
215 }
216
217 if (first || atof(PQgetvalue(res, 0, 0)) < xmin) xmin = atof(PQgetvalue(res, 0, 0));
218 if (first || atof(PQgetvalue(res, 0, 1)) < ymin) ymin = atof(PQgetvalue(res, 0, 1));
219 if (first || atof(PQgetvalue(res, 0, 2)) > xmax) xmax = atof(PQgetvalue(res, 0, 2));
220 if (first || atof(PQgetvalue(res, 0, 3)) > ymax) ymax = atof(PQgetvalue(res, 0, 3));
221
222 first = false;
223 PQclear(res);
224 }
225
226 buffer_free(sql);
227
228 bb = ows_bbox_init();
229 ows_bbox_set(o, bb, xmin, ymin, xmax, ymax, 4326);
231 ows_bbox_free(bb);
232
233 return g;
234}
235
236
237#ifdef OWS_DEBUG
238/*
239 * Flush bbox value to a file (mainly to debug purpose)
240 */
241void ows_geobbox_flush(const ows_geobbox * g, FILE * output)
242{
243 assert(g);
244 assert(output);
245
246 fprintf(output, "[W:%f,E:%f,S:%f,N:%f]\n", g->west, g->east, g->south, g->north);
247}
248#endif
249
250
251/*
252 * vim: expandtab sw=4 ts=4
253 */
void ows_bbox_free(ows_bbox *b)
Definition ows_bbox.c:58
void buffer_empty(buffer *buf)
Definition buffer.c:100
ows_bbox * ows_bbox_init()
Definition ows_bbox.c:37
PGresult * ows_psql_exec(ows *o, const char *sql)
Definition ows_psql.c:56
void buffer_copy(buffer *dest, const buffer *src)
Definition buffer.c:350
list * ows_psql_geometry_column(ows *o, buffer *layer_name)
Definition ows_psql.c:76
void buffer_add_str(buffer *buf, const char *str)
Definition buffer.c:254
bool ows_bbox_set_from_str(ows *o, ows_bbox *bb, const char *str, int srid, bool honours_authority_axis_order_if_no_explicit_srs)
Definition ows_bbox.c:96
bool ows_bbox_set(ows *o, ows_bbox *b, double xmin, double ymin, double xmax, double ymax, int srid)
Definition ows_bbox.c:71
void buffer_free(buffer *buf)
Definition buffer.c:83
void ows_geobbox_flush(const ows_geobbox *g, FILE *output)
buffer * buffer_init()
Definition buffer.c:61
buffer * ows_psql_table_name(ows *o, buffer *layer_name)
Definition ows_psql.c:116
buffer * ows_psql_schema_name(ows *o, buffer *layer_name)
Definition ows_psql.c:96
ows_geobbox * ows_geobbox_compute(ows *o, buffer *layer_name)
bool ows_geobbox_set_from_bbox(ows *o, ows_geobbox *g, ows_bbox *bb)
void ows_geobbox_free(ows_geobbox *g)
Definition ows_geobbox.c:69
ows_geobbox * ows_geobbox_copy(ows_geobbox *g)
Definition ows_geobbox.c:56
ows_geobbox * ows_geobbox_init()
Definition ows_geobbox.c:37
bool ows_geobbox_set(ows *o, ows_geobbox *g, double west, double east, double south, double north)
Definition ows_geobbox.c:80
ows_geobbox * ows_geobbox_set_from_str(ows *o, ows_geobbox *g, char *str)
struct List_node list_node
struct Buffer buffer
struct Ows ows
struct Ows_bbox ows_bbox
struct Ows_geobbox ows_geobbox
struct List list
char * buf
size to next realloc
Definition ows_struct.h:39
struct List_node * next
Definition ows_struct.h:45
buffer * value
Definition ows_struct.h:44
list_node * first
Definition ows_struct.h:50
double xmax
Definition ows_struct.h:137
double ymin
Definition ows_struct.h:136
double ymax
Definition ows_struct.h:138
double xmin
Definition ows_struct.h:135
double east
Definition ows_struct.h:143
double south
Definition ows_struct.h:145
double north
Definition ows_struct.h:146
double west
Definition ows_struct.h:144
bool estimated_extent
Definition ows_struct.h:395

Generated for tinyows by doxygen 1.13.2