tinyows 1.2.2
fe_spatial_ops.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 <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <assert.h>
28
29#include "../ows/ows.h"
30
31
32/*
33 * Check if the string is a spatial operator
34 */
35bool fe_is_spatial_op(char *name)
36{
37 assert(name);
38
39 /* case sensitive comparison because the gml standard specifies
40 strictly the name of the operator */
41 if ( !strcmp(name, "Equals")
42 || !strcmp(name, "Disjoint")
43 || !strcmp(name, "Touches")
44 || !strcmp(name, "Within")
45 || !strcmp(name, "Overlaps")
46 || !strcmp(name, "Crosses")
47 || !strcmp(name, "Intersects")
48 || !strcmp(name, "Contains")
49 || !strcmp(name, "DWithin")
50 || !strcmp(name, "Beyond")
51 || !strcmp(name, "BBOX"))
52 return true;
53
54 return false;
55}
56
57
58/*
59 * Transform syntax coordinates from GML 2.1.2 (x1,y1 x2,y2) into Postgis (x1 y1,x2 y2)
60 */
62{
63 size_t i;
64 assert(coord);
65
66 /*check if the first separator is a comma else do nothing */
67 if (check_regexp(coord->buf, "^[0-9.-]+,")) {
68 for (i = 0; i < coord->use; i++) {
69 if (coord->buf[i] == ' ') coord->buf[i] = ',';
70 else if (coord->buf[i] == ',') coord->buf[i] = ' ';
71 }
72 }
73
74 return coord;
75}
76
77
78/*
79 * Write a polygon geometry according to postgresql syntax from GML bbox
80 */
81buffer *fe_envelope(ows * o, buffer * typename, filter_encoding * fe, buffer *envelope, xmlNodePtr n)
82{
83 list *coord_min, *coord_max, *coord_pair;
84 xmlChar *content, *srsname;
85 buffer *name, *tmp;
86 ows_bbox *bbox;
87 int srid_int;
88 bool ret;
89 ows_srs *s = NULL;
90
91 assert(o);
92 assert(n);
93 assert(fe);
94 assert(typename);
95 assert(envelope);
96
97 name = buffer_init();
98 buffer_add_str(name, (char *) n->name);
99
100 srsname = xmlGetProp(n, (xmlChar *) "srsName");
101 if (srsname) {
102 s = ows_srs_init();
103
104 if (!ows_srs_set_from_srsname(o, s, (char *) srsname)) {
106 xmlFree(srsname);
107 buffer_free(name);
108 ows_srs_free(s);
109 return envelope;
110 }
111
112 xmlFree(srsname);
113 srid_int = s->srid;
114 } else {
115 if (o->request->request.wfs->srs)
116 srid_int = o->request->request.wfs->srs->srid;
117 else
119 }
120
121 n = n->children;
122 while (n->type != XML_ELEMENT_NODE) n = n->next; /* Jump to next element if spaces */
123
124 content = xmlNodeGetContent(n->children);
125
126 /* GML3 */
127 if (!strcmp((char *) n->name, "lowerCorner")) {
128 if (!content || !check_regexp((char *) content,
129 "[-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)? [-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)?")) {
130 xmlFree(content);
131 buffer_free(name);
132 if (s) ows_srs_free(s);
134
135 return envelope;
136 }
137 coord_min = list_explode_str(' ', (char *) content);
138
139
140 n = n->next;
141 while (n->next && n->type != XML_ELEMENT_NODE) n = n->next; /* Jump to next element if spaces */
142 xmlFree(content);
143 content = xmlNodeGetContent(n->children);
144
145 if (!content || !check_regexp((char *) content,
146 "[-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)? [-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)?")) {
147 xmlFree(content);
148 buffer_free(name);
149 list_free(coord_min);
150 if (s) ows_srs_free(s);
152
153 return envelope;
154 }
155 coord_max = list_explode_str(' ', (char *) content);
156
157 /* GML2 */
158 } else if (!strcmp((char *) n->name, "coordinates")) {
159 tmp = buffer_init();
160 buffer_add_str(tmp, (char *) content);
161 if (!check_regexp((char *) content, "^[-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)?,[-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)?[ ][-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)?,[-]?[0-9]+([.][0-9]+)?([eE][-]?[0-9]+)?$")) {
162 xmlFree(content);
163 buffer_free(name);
164 if (s) ows_srs_free(s);
166
167 return envelope;
168 }
170 coord_pair = list_explode(',', tmp);
171 coord_min = list_explode(' ', coord_pair->first->value);
172 coord_max = list_explode(' ', coord_pair->first->next->value);
173 buffer_free(tmp);
174 list_free(coord_pair);
175 } else {
176 /* FIXME handle coord and pos */
177 xmlFree(content);
178 buffer_free(name);
179 if (s) ows_srs_free(s);
181
182 return envelope;
183 }
184
185 buffer_free(name);
186 xmlFree(content);
187
188 /* return the polygon's coordinates matching the bbox */
189 bbox = ows_bbox_init();
191 ret = ows_bbox_set(o, bbox,
192 atof(coord_min->first->next->value->buf),
193 atof(coord_min->first->value->buf),
194 atof(coord_max->first->next->value->buf),
195 atof(coord_max->first->value->buf),
196 srid_int);
197 } else {
198 ret = ows_bbox_set(o, bbox,
199 atof(coord_min->first->value->buf),
200 atof(coord_min->first->next->value->buf),
201 atof(coord_max->first->value->buf),
202 atof(coord_max->first->next->value->buf),
203 srid_int);
204 }
205
206 if (!ret) {
208 list_free(coord_min);
209 list_free(coord_max);
210 ows_bbox_free(bbox);
211 if (s) ows_srs_free(s);
212
213 return envelope;
214 }
215
216 list_free(coord_min);
217 list_free(coord_max);
218
219 ows_bbox_to_query(o, bbox, envelope);
220 ows_bbox_free(bbox);
221 if (s) ows_srs_free(s);
222
223 return envelope;
224}
225
226
227/*
228 * Return the SQL request matching the spatial operator
229 */
230static buffer *fe_spatial_functions(ows * o, buffer * typename, filter_encoding * fe, xmlNodePtr n)
231{
232 ows_srs *s;
233 buffer *geom, *layer_name;
234 xmlNodePtr p;
235 xmlChar *srsname;
236 ows_srs* parent_srs = NULL;
237 bool free_parent_srs = false;
238
239 assert(typename);
240 assert(fe);
241 assert(n);
242 assert(o);
243
244 if (!strcmp((char *) n->name, "Equals")) buffer_add_str(fe->sql, " ST_Equals(");
245 if (!strcmp((char *) n->name, "Disjoint")) buffer_add_str(fe->sql, " ST_Disjoint(");
246 if (!strcmp((char *) n->name, "Touches")) buffer_add_str(fe->sql, " ST_Touches(");
247 if (!strcmp((char *) n->name, "Within")) buffer_add_str(fe->sql, " ST_Within(");
248 if (!strcmp((char *) n->name, "Overlaps")) buffer_add_str(fe->sql, " ST_Overlaps(");
249 if (!strcmp((char *) n->name, "Crosses")) buffer_add_str(fe->sql, " ST_Crosses(");
250 if (!strcmp((char *) n->name, "Intersects")) buffer_add_str(fe->sql, " ST_Intersects(");
251 if (!strcmp((char *) n->name, "Contains")) buffer_add_str(fe->sql, " ST_Contains(");
252
253 n = n->children;
254 while (n->type != XML_ELEMENT_NODE) n = n->next; /* Jump to next element if spaces */
255
256 p = n;
257 n = n->next;
258
259 layer_name = ows_layer_prefix_to_uri(o->layers, typename);
260
261 /* jump to the next element if there are spaces */
262 while (n->type != XML_ELEMENT_NODE) n = n->next;
263
264 if (o->request->request.wfs->srs) {
265 parent_srs = o->request->request.wfs->srs;
266 }
267 else {
268 int srid = ows_srs_get_srid_from_layer(o, layer_name);
269 if (srid > 0) {
270 parent_srs = ows_srs_init();
271 ows_srs_set_from_srid(o, parent_srs, srid);
272 free_parent_srs = true;
273 }
274 }
275
276 if (!strcmp((char *) n->name, "Box") || !strcmp((char *) n->name, "Envelope")) {
277 int srid = -1;
278 srsname = xmlGetProp(n, (xmlChar *) "srsName");
279 if (srsname) {
280 s = ows_srs_init();
281 if (ows_srs_set_from_srsname(o, s, (char *) srsname)) srid = s->srid;
282 ows_srs_free(s);
283 xmlFree(srsname);
284 }
285
286 buffer_add(fe->sql, '"');
287 fe->sql = fe_property_name(o, typename, fe, fe->sql, p, true, true);
288 buffer_add(fe->sql, '"');
289 buffer_add(fe->sql, ',');
290
291 if (srid != ows_srs_get_srid_from_layer(o, layer_name)) {
292 buffer_add_str(fe->sql, "ST_Transform(");
293 fe->sql = fe_envelope(o, typename, fe, fe->sql, n);
294 buffer_add(fe->sql, ',');
296 buffer_add(fe->sql, ')');
297 } else fe->sql = fe_envelope(o, typename, fe, fe->sql, n);
298
299 } else {
300 int srid;
301 geom = ows_psql_gml_to_sql(o, n, parent_srs);
302 if (!geom) {
304 if (free_parent_srs)
305 ows_srs_free(parent_srs);
306 return fe->sql;
307 }
308
309 srid = ows_psql_geometry_srid(o, geom->buf);
310
311 buffer_add(fe->sql, '"');
312 fe->sql = fe_property_name(o, typename, fe, fe->sql, p, true, true);
313 buffer_add(fe->sql, '"');
314 buffer_add(fe->sql, ',');
315
316 if (srid != ows_srs_get_srid_from_layer(o, layer_name))
317 buffer_add_str(fe->sql, "ST_Transform(");
318
319 buffer_add_str(fe->sql, "ST_SetSRID('");
320 buffer_copy(fe->sql, geom);
321 buffer_add_str(fe->sql, "'::geometry,");
322 buffer_add_int(fe->sql, srid);
323 buffer_add(fe->sql, ')');
324 buffer_free(geom);
325
326 if (srid != ows_srs_get_srid_from_layer(o, layer_name)) {
327 buffer_add(fe->sql, ',');
329 buffer_add(fe->sql, ')');
330 }
331 }
332
333 buffer_add(fe->sql, ')');
334
335 if (free_parent_srs)
336 ows_srs_free(parent_srs);
337
338 return fe->sql;
339}
340
341
342/*
343 * DWithin and Beyond operators : test if a geometry A is within (or beyond)
344 * a specified distance of a geometry B
345 */
346static buffer *fe_distance_functions(ows * o, buffer * typename, filter_encoding * fe, xmlNodePtr n)
347{
348 xmlChar *content, *units;
349 buffer *tmp, *op, *sql, *layer_name;
350 float km;
351
352 assert(o);
353 assert(typename);
354 assert(fe);
355 assert(n);
356
357 tmp = NULL;
358 op = buffer_init();
359
360 layer_name = ows_layer_prefix_to_uri(o->layers, typename);
361
362 if (!strcmp((char *) n->name, "Beyond")) buffer_add_str(op, " > ");
363 if (!strcmp((char *) n->name, "DWithin")) buffer_add_str(op, " < ");
364
365 buffer_add_str(fe->sql, "ST_Distance(");
366 if (!ows_srs_meter_units(o, layer_name))
367 buffer_add_str(fe->sql, "ST_Transform(");
368
369 n = n->children;
370 while (n->type != XML_ELEMENT_NODE) n = n->next; /* Jump to next element if spaces */
371
372 buffer_add(fe->sql, '"');
373 fe->sql = fe_property_name(o, typename, fe, fe->sql, n, true, true);
374 buffer_add(fe->sql, '"');
375
376 if (!ows_srs_meter_units(o, layer_name))
377 buffer_add_str(fe->sql, ", 4326)::geography");
378
379 buffer_add_str(fe->sql, "),('");
380
381 n = n->next;
382
383 while (n->type != XML_ELEMENT_NODE) n = n->next;
384
385 if (!ows_srs_meter_units(o, layer_name))
386 buffer_add_str(fe->sql, "ST_Transform(");
387
388 /* display the geometry */
389 sql = ows_psql_gml_to_sql(o, n, NULL);
390 if (sql) {
391 buffer_copy(fe->sql, sql);
392 buffer_free(sql);
393 } else fe->error_code = FE_ERROR_GEOMETRY;
394
395 if (!ows_srs_meter_units(o, layer_name))
396 buffer_add_str(fe->sql, ", 4326)::geography");
397
398 buffer_add_str(fe->sql, "'))");
399
400 n = n->next;
401
402 while (n->type != XML_ELEMENT_NODE) n = n->next;
403
404 units = xmlGetProp(n, (xmlChar *) "units");
405 buffer_copy(fe->sql, op);
406 content = xmlNodeGetContent(n->children);
407
408 /* units not strictly defined in Filter Encoding specification */
409 if (!strcmp((char *) units, "meters") || !strcmp((char *) units, "#metre"))
410 buffer_add_str(fe->sql, (char *) content);
411 else if (!strcmp((char *) units, "kilometers") || !strcmp((char *) units, "#kilometre")) {
412 km = atof((char *) content) * 1000.0;
413 tmp = buffer_ftoa((double) km);
414 buffer_copy(fe->sql, tmp);
415 buffer_free(tmp);
416 } else {
418 }
419
420 buffer_free(op);
421 xmlFree(content);
422 xmlFree(units);
423
424 return fe->sql;
425}
426
427
428static buffer *fe_bbox_layer(ows *o, buffer *typename, buffer *sql, buffer *propertyname, buffer *envelope)
429{
430 int srid = -1;
431 bool transform = false;
432
433 assert(propertyname);
434 assert(envelope);
435 assert(sql);
436 assert(o);
437
438 buffer_add_str(sql, "(_ST_Intersects(");
439
440 if (o->request->request.wfs->srs) {
441 srid = o->request->request.wfs->srs->srid;
442 transform = true;
443 }
444
445 if (transform) buffer_add_str(sql, "ST_Transform(");
446
447 buffer_add(sql, '"');
448 buffer_copy(sql, propertyname);
449 buffer_add(sql, '"');
450
451 if (transform) {
452 buffer_add(sql, ',');
453 buffer_add_int(sql, srid);
454 buffer_add(sql, ')');
455 }
456
457 buffer_add_str(sql, ",");
458 if (transform) buffer_add_str(sql, "ST_Transform(");
459 buffer_copy(sql, envelope);
460 if (transform) {
461 buffer_add(sql, ',');
462 buffer_add_int(sql, srid);
463 buffer_add(sql, ')');
464 }
465 buffer_add_str(sql, ") AND ");
466 if (transform) buffer_add_str(sql, "ST_Transform(");
467
468 buffer_add(sql, '"');
469 buffer_copy(sql, propertyname);
470 buffer_add(sql, '"');
471
472 if (transform) {
473 buffer_add(sql, ',');
474 buffer_add_int(sql, srid);
475 buffer_add(sql, ')');
476 }
477
478 buffer_add_str(sql, " && ");
479 if (transform) buffer_add_str(sql, "ST_Transform(");
480 buffer_copy(sql, envelope);
481 if (transform) {
482 buffer_add(sql, ',');
483 buffer_add_int(sql, srid);
484 buffer_add(sql, ')');
485 }
486 buffer_add_str(sql, ")");
487
488 return sql;
489}
490
491
492/*
493 * BBOX operator : identify all geometries that spatially interact with the specified box
494 */
495static buffer *fe_bbox(ows * o, buffer * typename, filter_encoding * fe, xmlNodePtr n)
496{
497 buffer *property, *layer_name;
498 list *columns;
499 list_node *ln;
500 buffer *envelope = NULL;
501
502 assert(o);
503 assert(typename);
504 assert(fe);
505 assert(n);
506
507 n = n->children;
508 while (n->type != XML_ELEMENT_NODE) n = n->next;
509
510 layer_name = ows_layer_prefix_to_uri(o->layers, typename);
511 columns = ows_psql_geometry_column(o, layer_name);
512
513 /* Retrieve the property name */
514 property = buffer_init();
515 property = fe_property_name(o, typename, fe, property, n, true, false);
516 if (fe->error_code != FE_NO_ERROR) {
517 buffer_free(property);
518 return fe->sql;
519 }
520
521 /* If no property name, so we have to check with each Geometry_columns */
522 if (property->use == 0) {
523
524 /* retrieve the geometry matching the bbox */
525 if (!strcmp((char *) n->name, "Box") || !strcmp((char *) n->name, "Envelope")) {
526 envelope = buffer_init();
527 envelope = fe_envelope(o, layer_name, fe, envelope, n);
528 } else {
530 }
531
532 buffer_add(fe->sql, '(');
533 for (ln = columns->first ; ln ; ln = ln->next) {
534 if (envelope) fe->sql = fe_bbox_layer(o, typename, fe->sql, ln->value, envelope);
535 if (ln->next && (fe->in_not == 0 || !fe->in_not%2)) buffer_add_str(fe->sql, " OR ");
536 else if (ln->next && fe->in_not%2) buffer_add_str(fe->sql, " AND ");
537 else buffer_add_str(fe->sql, ")");
538 }
539
540 } else {
541 n = n->next;
542 while (n->type != XML_ELEMENT_NODE) n = n->next;
543
544 if (!strcmp((char *) n->name, "Box") || !strcmp((char *) n->name, "Envelope")) {
545 if (!in_list(columns, property)) {
546 buffer_free(property);
548 return fe->sql;
549 }
550 envelope = buffer_init();
551 envelope = fe_envelope(o, layer_name, fe, envelope, n);
552 } else {
554 }
555
556 if (envelope) fe->sql = fe_bbox_layer(o, typename, fe->sql, property, envelope);
557 }
558
559 if (envelope) buffer_free(envelope);
560 buffer_free(property);
561 return fe->sql;
562}
563
564
565/*
566 * Print the SQL request matching spatial function (Equals,Disjoint, etc)
567 * Warning : before calling this function,
568 * Check if the node name is a spatial operator with fe_is_spatial_op()
569 */
570buffer *fe_spatial_op(ows * o, buffer * typename, filter_encoding * fe, xmlNodePtr n)
571{
572 assert(o);
573 assert(typename);
574 assert(fe);
575 assert(n);
576
577 /* case sensitive comparison because the gml standard specifies
578 strictly the name of the operator */
579 if ( !strcmp((char *) n->name, "Equals")
580 || !strcmp((char *) n->name, "Disjoint")
581 || !strcmp((char *) n->name, "Touches")
582 || !strcmp((char *) n->name, "Within")
583 || !strcmp((char *) n->name, "Overlaps")
584 || !strcmp((char *) n->name, "Crosses")
585 || !strcmp((char *) n->name, "Intersects")
586 || !strcmp((char *) n->name, "Contains"))
587 fe->sql = fe_spatial_functions(o, typename, fe, n);
588 else if (!strcmp((char *) n->name, "DWithin") || !strcmp((char *) n->name, "Beyond"))
589 fe->sql = fe_distance_functions(o, typename, fe, n);
590 else if (!strcmp((char *) n->name, "BBOX"))
591 fe->sql = fe_bbox(o, typename, fe, n);
592 else
594
595 return fe->sql;
596}
597
598
599/*
600 * vim: expandtab sw=4 ts=4
601 */
static buffer * fe_transform_coord_gml2_to_psql(buffer *coord)
static buffer * fe_bbox(ows *o, buffer *typename, filter_encoding *fe, xmlNodePtr n)
static buffer * fe_bbox_layer(ows *o, buffer *typename, buffer *sql, buffer *propertyname, buffer *envelope)
buffer * fe_envelope(ows *o, buffer *typename, filter_encoding *fe, buffer *envelope, xmlNodePtr n)
bool fe_is_spatial_op(char *name)
static buffer * fe_distance_functions(ows *o, buffer *typename, filter_encoding *fe, xmlNodePtr n)
buffer * fe_spatial_op(ows *o, buffer *typename, filter_encoding *fe, xmlNodePtr n)
static buffer * fe_spatial_functions(ows *o, buffer *typename, filter_encoding *fe, xmlNodePtr n)
void ows_bbox_free(ows_bbox *b)
Definition ows_bbox.c:58
int ows_psql_geometry_srid(ows *o, const char *geom)
Definition ows_psql.c:861
void buffer_add(buffer *buf, char c)
Definition buffer.c:123
ows_bbox * ows_bbox_init()
Definition ows_bbox.c:37
buffer * ows_psql_gml_to_sql(ows *o, xmlNodePtr n, const ows_srs *parent_srs)
Definition ows_psql.c:734
void buffer_copy(buffer *dest, const buffer *src)
Definition buffer.c:350
bool ows_srs_meter_units(ows *o, buffer *layer_name)
Definition ows_srs.c:361
ows_srs * ows_srs_init()
Definition ows_srs.c:37
list * ows_psql_geometry_column(ows *o, buffer *layer_name)
Definition ows_psql.c:76
bool in_list(const list *l, const buffer *value)
Definition list.c:259
void list_free(list *l)
Definition list.c:54
void buffer_add_str(buffer *buf, const char *str)
Definition buffer.c:254
bool ows_srs_set_from_srsname(ows *o, ows_srs *s, const char *srsname)
Definition ows_srs.c:303
bool ows_srs_set_from_srid(ows *o, ows_srs *s, int srid)
Definition ows_srs.c:251
void ows_bbox_to_query(ows *o, ows_bbox *bbox, buffer *query)
Definition ows_bbox.c:285
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 buffer_add_int(buffer *buf, int i)
Definition buffer.c:173
int ows_srs_get_srid_from_layer(ows *o, buffer *layer_name)
Definition ows_srs.c:380
buffer * buffer_ftoa(double f)
Definition buffer.c:138
void ows_srs_free(ows_srs *c)
Definition ows_srs.c:76
buffer * buffer_init()
Definition buffer.c:61
buffer * fe_property_name(ows *o, buffer *typename, filter_encoding *fe, buffer *sql, xmlNodePtr n, bool check_geom_column, bool mandatory)
Definition fe_filter.c:210
list * list_explode(char separator, const buffer *value)
Definition list.c:296
bool check_regexp(const char *str_request, const char *str_regex)
Definition regexp.c:36
buffer * ows_layer_prefix_to_uri(ows_layer_list *ll, buffer *layer_name_prefix)
Definition ows_layer.c:343
list * list_explode_str(char separator, const char *value)
Definition list.c:401
struct List_node list_node
struct Buffer buffer
struct Ows ows
@ FE_NO_ERROR
Definition ows_struct.h:328
@ FE_ERROR_UNITS
Definition ows_struct.h:334
@ FE_ERROR_FILTER
Definition ows_struct.h:330
@ FE_ERROR_SRS
Definition ows_struct.h:337
@ FE_ERROR_GEOM_PROPERTYNAME
Definition ows_struct.h:333
@ FE_ERROR_BBOX
Definition ows_struct.h:331
@ FE_ERROR_GEOMETRY
Definition ows_struct.h:335
struct Ows_srs ows_srs
struct Ows_bbox ows_bbox
struct Filter_encoding filter_encoding
struct List list
char * buf
size to next realloc
Definition ows_struct.h:39
size_t use
Definition ows_struct.h:36
enum fe_error_code error_code
Definition ows_struct.h:346
struct List_node * next
Definition ows_struct.h:45
buffer * value
Definition ows_struct.h:44
list_node * first
Definition ows_struct.h:50
wfs_request * wfs
Definition ows_struct.h:357
union Ows_request::@061103224255043274127022210112340325046267027263 request
bool honours_authority_axis_order
Definition ows_struct.h:126
bool is_axis_order_gis_friendly
Definition ows_struct.h:118
ows_request * request
Definition ows_struct.h:403
ows_layer_list * layers
Definition ows_struct.h:402

Generated for tinyows by doxygen 1.14.0