49 if (!srs->
srid || srs->
srid == -1 || (xmin == ymin && xmax == ymax && xmin == xmax)) {
51 fprintf(o->
output,
"<gml:boundedBy><gml:null>missing</gml:null></gml:boundedBy>\n");
55 fprintf(o->
output,
"<gml:boundedBy>\n");
58 fprintf(o->
output,
" <gml:Box srsName=\"");
60 else if (srs->
is_long) fprintf(o->
output,
"urn:ogc:def:crs:EPSG::");
61 else fprintf(o->
output,
"EPSG:");
66 fprintf(o->
output,
"<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">%g,%g %g,%g</gml:coordinates>",
67 xmin, ymin, xmax, ymax);
68 else fprintf(o->
output,
"<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">%.*f,%.*f %.*f,%.*f</gml:coordinates>",
69 precision, xmin, precision, ymin, precision, xmax, precision, ymax);
70 fprintf(o->
output,
"</gml:Box>\n");
73 fprintf(o->
output,
" <gml:Envelope srsName=\"");
75 else if (srs->
is_long) fprintf(o->
output,
"urn:ogc:def:crs:EPSG::");
76 else fprintf(o->
output,
"EPSG:");
82 fprintf(o->
output,
"<gml:lowerCorner>%g %g</gml:lowerCorner>", ymin, xmin);
83 fprintf(o->
output,
"<gml:upperCorner>%g %g</gml:upperCorner>", ymax, xmax);
85 fprintf(o->
output,
"<gml:lowerCorner>%.*f %.*f</gml:lowerCorner>", precision, ymin, precision, xmin);
86 fprintf(o->
output,
"<gml:upperCorner>%.*f %.*f</gml:upperCorner>", precision, ymax, precision, xmax);
91 fprintf(o->
output,
"<gml:lowerCorner>%g %g</gml:lowerCorner>", xmin, ymin);
92 fprintf(o->
output,
"<gml:upperCorner>%g %g</gml:upperCorner>", xmax, ymax);
94 fprintf(o->
output,
"<gml:lowerCorner>%.*f %.*f</gml:lowerCorner>", precision, xmin, precision, ymin);
95 fprintf(o->
output,
"<gml:upperCorner>%.*f %.*f</gml:upperCorner>", precision, xmax, precision, ymax);
98 fprintf(o->
output,
"</gml:Envelope>\n");
101 fprintf(o->
output,
"</gml:boundedBy>\n");
111 char * prop_name,
buffer * prop_type,
char * value)
113 buffer *time, *pkey, *value_encoded, *prop_name_buffer;
115 assert(layer_name && prop_name);
119 assert(layer_name && prop_name && prop_type && prefix && value && wr && o);
124 if (pkey && pkey->
buf && !strcmp(prop_name, pkey->
buf) && !o->
expose_pk)
return;
134 if (strlen(value) == 0)
return;
140 if (gml_ns) fprintf(o->
output,
" <gml:%s>", prop_name);
141 else fprintf(o->
output,
" <%s:%s>", prefix->
buf, prop_name);
155 if (!strcmp(value,
"t")) fprintf(o->
output,
"true");
156 if (!strcmp(value,
"f")) fprintf(o->
output,
"false");
164 fprintf(o->
output,
"%s", value_encoded->
buf);
167 }
else fprintf(o->
output,
"%s", value);
169 if (gml_ns) fprintf(o->
output,
"</gml:%s>\n", prop_name);
170 else fprintf(o->
output,
"</%s:%s>\n", prefix->
buf, prop_name);
179 int i, j, number, end, nb_fields;
180 buffer *id_name, *ns_prefix, *prop_type, *layer;
182 assert(o && wr && res && layer_name);
190 if (id_name && id_name->
use) number = PQfnumber(res, id_name->
buf);
196 for (i = 0, end = PQntuples(res); i < end; i++) {
197 fprintf(o->
output,
" <gml:featureMember>\n");
202 if (id_name && id_name->
use) {
204 fprintf(o->
output,
" <%s gml:id=\"%s.%s\">\n",
206 layer->
buf, PQgetvalue(res, i, number));
207 else fprintf(o->
output,
" <%s fid=\"%s.%s\">\n",
209 layer->
buf, PQgetvalue(res, i, number));
213 for (j = 0, nb_fields = PQnfields(res) ; j < nb_fields ; j++) {
221 prop_type =
array_get(describe, PQfname(res, j));
227 fprintf(o->
output,
" </gml:featureMember>\n");
248 fprintf(o->
output,
"Content-Type: text/xml; subtype=gml/2.1.2\n\n");
250 fprintf(o->
output,
"Content-Type: text/xml; subtype=gml/3.1.1\n\n");
253 fprintf(o->
output,
"<wfs:FeatureCollection\n");
255 for (an = namespaces->
first; an != NULL; an = an->
next)
258 fprintf(o->
output,
" xmlns:wfs='http://www.opengis.net/wfs'\n");
259 fprintf(o->
output,
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n");
260 fprintf(o->
output,
" xmlns:gml='http://www.opengis.net/gml'\n");
261 fprintf(o->
output,
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'\n");
262 fprintf(o->
output,
" xmlns:ogc='http://www.opengis.net/ogc'\n");
263 fprintf(o->
output,
" xmlns:xlink='http://www.w3.org/1999/xlink'\n");
264 fprintf(o->
output,
" xmlns:ows='http://www.opengis.net/ows'\n");
266 fprintf(o->
output,
" xsi:schemaLocation='");
268 fprintf(o->
output,
"%s\n %s?service=WFS&version=1.0.0&request=DescribeFeatureType",
271 fprintf(o->
output,
"%s\n %s?service=WFS&version=1.1.0&request=DescribeFeatureType",
276 fprintf(o->
output,
"&Typename=");
277 for (ln = wr->typename->first ; ln ; ln = ln->
next) {
284 fprintf(o->
output,
" http://www.opengis.net/wfs\n");
285 fprintf(o->
output,
" http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd\n");
287 fprintf(o->
output,
" http://www.opengis.net/wfs\n");
288 fprintf(o->
output,
" http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\n");
292 fprintf(o->
output,
" http://www.opengis.net/gml\n");
293 fprintf(o->
output,
" http://schemas.opengis.net/gml/2.1.2/feature.xsd'\n");
295 fprintf(o->
output,
" http://www.opengis.net/gml\n");
296 fprintf(o->
output,
" http://schemas.opengis.net/gml/3.1.1/base/gml.xsd'\n");
315 assert(request_list);
325 if (PQresultStatus(res) == PGRES_TUPLES_OK)
326 hits = hits + atoi(PQgetvalue(res, 0, 0));
333 fprintf(o->
output,
" timeStamp='%s' numberOfFeatures='%d' />\n", date->
buf, hits);
345 buffer *layer_name, *layer_uri;
350 assert(o && wr && request_list);
352 ln = ln_typename = NULL;
353 mln_property = mln_fid = NULL;
357 fprintf(o->
output,
">\n");
367 if (wr->typename) ln_typename = wr->typename->first;
368 if (wr->featureid) mln_fid = wr->featureid->first;
369 if (wr->propertyname) mln_property = wr->propertyname->first;
375 if (PQresultStatus(res) != PGRES_TUPLES_OK) {
379 if (wr->typename) ln_typename = ln_typename->
next;
380 if (wr->featureid) mln_fid = mln_fid->
next;
381 if (wr->propertyname) mln_property = mln_property->
next;
406 if (wr->featureid) mln_fid = mln_fid->
next;
407 if (wr->propertyname) mln_property = mln_property->
next;
408 if (wr->typename) ln_typename = ln_typename->
next;
411 fprintf(o->
output,
"</wfs:FeatureCollection>\n");
433 for (an = prop_table->
first ; an ; an = an->
next) {
435 if (!strcmp(an->
key->
buf,
"boundedBy")
438 else gml_boundedby =
false;
460 if ((wr->srs && !wr->srs->is_geographic) ||
467 if (wr->srs && wr->srs->is_long) gml_opt += 1;
470 wr->srs->honours_authority_axis_order &&
471 !wr->srs->is_axis_order_gis_friendly ) gml_opt += 16;
472 if (gml_boundedby) gml_opt += 32;
499 if (wr->srs && wr->srs->is_long) gml_opt += 1;
500 if (gml_boundedby) gml_opt += 32;
502 if ((wr->srs && !wr->srs->is_geographic) || (!wr->srs &&
ows_srs_meter_units(o, layer_name))) {
508 wr->srs->honours_authority_axis_order &&
509 !wr->srs->is_axis_order_gis_friendly ) gml_opt += 16;
533 if ((wr->srs && !wr->srs->is_geographic) ||
567 list *fid, *sql_req, *from_list, *where_list;
569 buffer *geom, *sql, *where, *layer_name, *layer_uri, *sql_count;
570 int srid, size, cpt, features, max_features;
579 ln_typename = ln_filter = NULL;
585 size = wr->typename->size;
586 ln_typename = wr->typename->first;
589 if (wr->filter) ln_filter = wr->filter->first;
592 size = wr->featureid->size;
593 mln_fid = wr->featureid->first;
604 for (cpt = 0; cpt < size; cpt++) {
635 if (where->
use == 0) {
648 else if (wr->bbox) where =
fe_kvp_bbox(o, wr, layer_uri, wr->bbox);
651 else if (wr->filter) {
712 else if (wr->maxfeatures > 0)
713 max_features = wr->maxfeatures;
717 if (max_features > 0 && wr->typename->size == 1) {
720 }
else if (max_features > 0 && wr->typename->size > 1) {
730 if (PQresultStatus(res) == PGRES_TUPLES_OK) {
731 if (features + atoi(PQgetvalue(res, 0, 0)) <= max_features) {
733 if ((max_features - features) > 0)
736 features += atoi(PQgetvalue(res, 0, 0));
752 if (wr->featureid) mln_fid = mln_fid->
next;
753 if (wr->typename) ln_typename = ln_typename->
next;
754 if (wr->filter) ln_filter = ln_filter->
next;
776 buffer *prop, *value_enc, *geom, *id_name;
777 bool first_row, first_col;
784 assert(request_list);
795 assert(wr->callback);
797 fprintf(o->
output,
"Content-Type: application/javascript\n\n");
798 fprintf(o->
output,
"%s", wr->callback->buf);
801 }
else fprintf(o->
output,
"Content-Type: application/json\n\n");
804 fprintf(o->
output,
"{\"type\": \"FeatureCollection\", \"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"");
806 fprintf(o->
output,
"EPSG:%i", wr->srs->srid);
808 fprintf(o->
output,
"urn:ogc:def:crs:EPSG::%i", wr->srs->srid);
810 fprintf(o->
output,
"\"}}, \"features\": [");
815 if (PQresultStatus(res) != PGRES_TUPLES_OK) {
826 if (id_name && id_name->
use)
827 number = PQfnumber(res, id_name->
buf);
830 for (i=0 ; i < PQntuples(res) ; i++) {
835 if (first_row) first_row =
false;
836 else fprintf(o->
output,
",");
845 for (an = prop_table->
first, j=0 ; an ; an = an->
next, j++) {
852 if (first_col) first_col =
false;
866 "{\"type\":\"Feature\", %s\"properties\":{\"%s}}\n",
868 }
else if (geoms == 1) {
870 "{\"type\":\"Feature\", %s\"properties\":{\"%s}, \"geometry\":%s}\n",
872 }
else if (geoms > 1) {
874 "{\"type\":\"Feature\", %s\"properties\":{\"%s}, \"geometry\":%s%s]}}\n",
876 prop->
buf,
"{ \"type\": \"GeometryCollection\", \"geometries\": [",
906 if (!request_list)
return;
buffer * buffer_encode_xml_entities_str(const char *str)
list * ows_psql_not_null_properties(ows *o, buffer *layer_name)
void ows_bbox_free(ows_bbox *b)
void buffer_add(buffer *buf, char c)
int ows_version_get(ows_version *v)
void list_add_by_copy(list *l, buffer *value)
void buffer_empty(buffer *buf)
filter_encoding * fe_filter(ows *o, filter_encoding *fe, buffer *typename, buffer *xmlchar)
void mlist_add(mlist *ml, list *value)
ows_bbox * ows_bbox_init()
PGresult * ows_psql_exec(ows *o, const char *sql)
buffer * buffer_encode_json_str(const char *str)
void buffer_copy(buffer *dest, const buffer *src)
bool ows_bbox_set_from_geobbox(ows *o, ows_bbox *bb, ows_geobbox *geo)
void fe_error(ows *o, filter_encoding *fe)
ows_bbox * ows_bbox_boundaries(ows *o, list *from, list *where, ows_srs *srs)
bool ows_srs_meter_units(ows *o, buffer *layer_name)
filter_encoding * filter_encoding_init()
bool buffer_cmp(const buffer *buf, const char *str)
bool in_list(const list *l, const buffer *value)
void buffer_add_str(buffer *buf, const char *str)
char * ows_psql_escape_string(ows *o, const char *content)
array * ows_layer_list_namespaces(ows_layer_list *ll)
void ows_bbox_to_query(ows *o, ows_bbox *bbox, buffer *query)
buffer * array_get(const array *a, const char *key)
buffer * ows_psql_id_column(ows *o, buffer *layer_name)
void wfs_error(ows *o, wfs_request *wf, enum wfs_error_code code, char *message, char *locator)
bool in_list_str(const list *l, const char *value)
void array_free(array *a)
bool buffer_ncmp(const buffer *buf, const char *str, size_t n)
void list_add(list *l, buffer *value)
void filter_encoding_free(filter_encoding *fe)
void buffer_add_head_str(buffer *buf, char *str)
buffer * ows_layer_no_uri_to_uri(const ows_layer_list *ll, buffer *name_no_uri)
array * ows_psql_describe_table(ows *o, buffer *layer_name)
buffer * buffer_from_str(const char *str)
void buffer_free(buffer *buf)
buffer * ows_layer_uri_to_prefix(ows_layer_list *ll, buffer *layer_name)
buffer * ows_psql_timestamp_to_xml_time(char *timestamp)
void buffer_add_int(buffer *buf, int i)
buffer * ows_layer_ns_prefix(ows_layer_list *ll, buffer *layer_name_prefix)
buffer * ows_layer_no_uri(ows_layer_list *ll, buffer *layer_name)
ows_layer * ows_layer_get(const ows_layer_list *ll, const buffer *name)
int ows_srs_get_srid_from_layer(ows *o, buffer *layer_name)
bool ows_psql_is_geometry_column(ows *o, buffer *layer_name, buffer *column)
buffer * ows_psql_table_name(ows *o, buffer *layer_name)
list * list_explode(char separator, const buffer *value)
buffer * fe_kvp_featureid(ows *o, wfs_request *wr, buffer *layer_name, list *fid)
buffer * fe_kvp_bbox(ows *o, wfs_request *wr, buffer *layer_name, ows_bbox *bbox)
buffer * ows_layer_prefix_to_uri(ows_layer_list *ll, buffer *layer_name_prefix)
buffer * ows_psql_schema_name(ows *o, buffer *layer_name)
void mlist_free(mlist *ml)
char * buf
size to next realloc
enum fe_error_code error_code
bool honours_authority_axis_order
bool is_axis_order_gis_friendly
ows_geobbox * max_geobbox
static void wfs_gml_display_namespaces(ows *o, wfs_request *wr)
static void wfs_gml_display_hits(ows *o, wfs_request *wr, mlist *request_list)
static void wfs_gml_display_results(ows *o, wfs_request *wr, mlist *request_list)
static void wfs_geojson_display_results(ows *o, wfs_request *wr, mlist *request_list)
void wfs_gml_feature_member(ows *o, wfs_request *wr, buffer *layer_name, list *properties, PGresult *res)
void wfs_get_feature(ows *o, wfs_request *wr)
static buffer * wfs_retrieve_sql_request_select(ows *o, wfs_request *wr, buffer *layer_name)
static void wfs_gml_bounded_by(ows *o, wfs_request *wr, double xmin, double ymin, double xmax, double ymax, ows_srs *srs)
static mlist * wfs_retrieve_sql_request_list(ows *o, wfs_request *wr)
void wfs_gml_display_feature(ows *o, wfs_request *wr, buffer *layer_name, buffer *prefix, char *prop_name, buffer *prop_type, char *value)