/* * Parse the configuration file's limits element */ static void ows_parse_config_limits(ows * o, xmlTextReaderPtr r) { xmlChar *a; ows_geobbox *geo; assert(o); assert(r); a = xmlTextReaderGetAttribute(r, (xmlChar *) "features"); if (a) { o->max_features = atoi((char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "geobbox"); if (a) { geo = ows_geobbox_init(); if (ows_geobbox_set_from_str(o, geo, (char *) a)) o->max_geobbox = geo; else ows_geobbox_free(geo); xmlFree(a); } }
/* * Specifies the list of feature types available from the wfs * Used for both 1.0.0 && 1.1.0 versions */ static void wfs_feature_type_list(ows * o) { ows_layer_node *ln; ows_geobbox *gb; int srid_int; buffer *srid; buffer *srs; list_node *keyword, *l_srid; int s; bool writable, retrievable; assert(o); writable = false; retrievable = false; fprintf(o->output, " <FeatureTypeList>\n"); /* print global operations */ if ( ows_layer_list_retrievable(o->layers) || ows_layer_list_writable(o->layers)) fprintf(o->output, " <Operations>\n"); if (ows_layer_list_retrievable(o->layers)) { if (ows_version_get(o->request->version) == 100) fprintf(o->output, " <Query/>\n"); else if (ows_version_get(o->request->version) == 110) fprintf(o->output, " <Operation>Query</Operation>\n"); retrievable = true; } if (ows_layer_list_writable(o->layers)) { if (ows_version_get(o->request->version) == 100) { fprintf(o->output, " <Insert/>\n"); fprintf(o->output, " <Update/>\n"); fprintf(o->output, " <Delete/>\n"); } else if (ows_version_get(o->request->version) == 110) { fprintf(o->output, " <Operation>Insert</Operation>\n"); fprintf(o->output, " <Operation>Update</Operation>\n"); fprintf(o->output, " <Operation>Delete</Operation>\n"); } writable = true; } if ( ows_layer_list_retrievable(o->layers) || ows_layer_list_writable(o->layers)) fprintf(o->output, " </Operations>\n"); for (ln = o->layers->first ; ln ; ln = ln->next) { /* print each feature type */ if (ows_layer_match_table(o, ln->layer->name)) { fprintf(o->output, "<FeatureType xmlns:%s=\"%s\">\n", ln->layer->ns_prefix->buf, ln->layer->ns_uri->buf); /* name */ if (ln->layer->name) { for (s = 0; s < ln->layer->depth; s++) fprintf(o->output, " "); fprintf(o->output, " <Name>"); buffer_flush(ows_layer_uri_to_prefix(o->layers, ln->layer->name), o->output); fprintf(o->output, "</Name>\n"); } /* title */ if (ln->layer->title) { for (s = 0; s < ln->layer->depth; s++) fprintf(o->output, " "); fprintf(o->output, " <Title>"); buffer_flush(ln->layer->title, o->output); fprintf(o->output, "</Title>\n"); } /* abstract */ if (ln->layer->abstract) { for (s = 0; s < ln->layer->depth; s++) fprintf(o->output, " "); fprintf(o->output, " <Abstract>"); buffer_flush(ln->layer->abstract, o->output); fprintf(o->output, "</Abstract>\n"); } /* keywords */ if (ln->layer->keywords) { for (s = 0; s < ln->layer->depth; s++) fprintf(o->output, " "); fprintf(o->output, " <Keywords>"); for (keyword = ln->layer->keywords->first ; keyword ; keyword = keyword->next) { if (ows_version_get(o->request->version) == 100) { fprintf(o->output, "%s", keyword->value->buf); if (keyword->next) fprintf(o->output, ","); } else if (ows_version_get(o->request->version) == 110) { fprintf(o->output, " <Keyword>"); fprintf(o->output, "%s", keyword->value->buf); fprintf(o->output, "</Keyword>"); } } fprintf(o->output, "</Keywords>\n"); } /* SRS */ srid = buffer_init(); srid_int = ows_srs_get_srid_from_layer(o, ln->layer->name); buffer_add_int(srid, srid_int); srs = ows_srs_get_from_a_srid(o, srid_int); if (srs->use) { if (ows_version_get(o->request->version) == 100) { fprintf(o->output, " <SRS>"); buffer_flush(srs, o->output); fprintf(o->output, "</SRS>\n"); } else if (ows_version_get(o->request->version) == 110) { fprintf(o->output, " <DefaultSRS>urn:ogc:def:crs:EPSG::%s</DefaultSRS>\n", srid->buf); if (ln->layer->srid) { for (l_srid = ln->layer->srid->first; l_srid; l_srid = l_srid->next) { if (!buffer_cmp(srid, l_srid->value->buf)) { fprintf(o->output, " <OtherSRS>urn:ogc:def:crs:EPSG::%s</OtherSRS>\n", l_srid->value->buf); } } } } } else { if (ows_version_get(o->request->version) == 100) fprintf(o->output, " <SRS></SRS>\n"); else if (ows_version_get(o->request->version) == 110) fprintf(o->output, " <NoSRS/>"); } /* Operations */ if (retrievable != ln->layer->retrievable || writable != ln->layer->writable) { fprintf(o->output, " <Operations>\n"); if (retrievable == false && ln->layer->retrievable == true) { if (ows_version_get(o->request->version) == 100) fprintf(o->output, " <Query/>\n"); else if (ows_version_get(o->request->version) == 110) fprintf(o->output, " <Operation>Query</Operation>\n"); } if (writable == false && ln->layer->writable == true) { if (ows_version_get(o->request->version) == 100) { fprintf(o->output, " <Insert/>\n"); fprintf(o->output, " <Update/>\n"); fprintf(o->output, " <Delete/>\n"); } else if (ows_version_get(o->request->version) == 110) { fprintf(o->output, " <Operation>Insert</Operation>\n"); fprintf(o->output, " <Operation>Update</Operation>\n"); fprintf(o->output, " <Operation>Delete</Operation>\n"); } } fprintf(o->output, " </Operations>\n"); } /* Boundaries */ if (!ln->layer->geobbox) { gb = ows_geobbox_compute(o, ln->layer->name); } else { gb = ows_geobbox_init(); gb->west = ln->layer->geobbox->west; gb->east = ln->layer->geobbox->east; gb->south = ln->layer->geobbox->south; gb->north = ln->layer->geobbox->north; } assert(gb); for (s = 0; s < ln->layer->depth; s++) fprintf(o->output, " "); if (ows_version_get(o->request->version) == 100) fprintf(o->output, " <LatLongBoundingBox"); else if (ows_version_get(o->request->version) == 110) fprintf(o->output, " <ows:WGS84BoundingBox>"); if (gb->east != DBL_MIN) { if (ows_version_get(o->request->version) == 100) { if (gb->west < gb->east) fprintf(o->output, " minx='%.*f'", o->degree_precision, gb->west); else fprintf(o->output, " minx='%.*f'", o->degree_precision, gb->east); if (gb->north < gb->south) fprintf(o->output, " miny='%.*f'", o->degree_precision, gb->north); else fprintf(o->output, " miny='%.*f'", o->degree_precision, gb->south); if (gb->west < gb->east) fprintf(o->output, " maxx='%.*f'", o->degree_precision, gb->east); else fprintf(o->output, " maxx='%.*f'", o->degree_precision, gb->west); if (gb->north < gb->south) fprintf(o->output, " maxy='%.*f'", o->degree_precision, gb->south); else fprintf(o->output, " maxy='%.*f'", o->degree_precision, gb->north); fprintf(o->output, " />\n"); } else if (ows_version_get(o->request->version) == 110) { fprintf(o->output, " <ows:LowerCorner>%.*f %.*f</ows:LowerCorner>", o->degree_precision, gb->west, o->degree_precision, gb->south); fprintf(o->output, " <ows:UpperCorner>%.*f %.*f</ows:UpperCorner>", o->degree_precision, gb->east, o->degree_precision, gb->north); } } else { if (ows_version_get(o->request->version) == 100) { fprintf(o->output, " minx='0' miny='0' maxx='0' maxy='0'/>\n"); } else if (ows_version_get(o->request->version) == 110) { fprintf(o->output, " <ows:LowerCorner>0 0</ows:LowerCorner>"); fprintf(o->output, " <ows:UpperCorner>0 0</ows:UpperCorner>"); } } if (ows_version_get(o->request->version) == 110) fprintf(o->output, " </ows:WGS84BoundingBox>\n"); buffer_free(srid); buffer_free(srs); ows_geobbox_free(gb); fprintf(o->output, "</FeatureType>\n"); } } fprintf(o->output, " </FeatureTypeList>\n"); }
/* * Parse the configuration file's layer element and all child layers */ static void ows_parse_config_layer(ows * o, xmlTextReaderPtr r) { ows_layer *layer; xmlChar *a; list *l; assert(o); assert(r); layer = ows_layer_init(); layer->depth = xmlTextReaderDepth(r); layer->parent = ows_parse_config_layer_get_parent(o, layer->depth); a = xmlTextReaderGetAttribute(r, (xmlChar *) "table"); if (a) { buffer_add_str(layer->storage->table, (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "name"); if (a) { layer->name = buffer_init(); buffer_add_str(layer->name, (char *) a); if (!layer->storage->table->use) buffer_add_str(layer->storage->table, (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "title"); if (a) { layer->title = buffer_init(); buffer_add_str(layer->title, (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "abstract"); if (a) { layer->abstract = buffer_init(); buffer_add_str(layer->abstract, (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "keywords"); if (a) { layer->keywords = list_explode_str(',', (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "gml_ns"); if (a) { layer->gml_ns = list_explode_str(',', (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "schema"); if (a) { buffer_add_str(layer->storage->schema, (char *) a); xmlFree(a); } else buffer_add_str(layer->storage->schema, "public"); /* inherits from layer parent and replaces with specified value if defined */ a = xmlTextReaderGetAttribute(r, (xmlChar *) "retrievable"); if (a && atoi((char *) a) == 1) { layer->retrievable = true; xmlFree(a); } else if (!a && layer->parent && layer->parent->retrievable) layer->retrievable = true; else xmlFree(a); /* inherits from layer parent and replaces with specified value if defined */ a = xmlTextReaderGetAttribute(r, (xmlChar *) "writable"); if (a && atoi((char *) a) == 1) { layer->writable = true; xmlFree(a); } else if (!a && layer->parent && layer->parent->writable) layer->writable = true; else xmlFree(a); /* inherits from layer parent and adds specified value */ if (layer->parent && layer->parent->srid) { layer->srid = list_init(); list_add_list(layer->srid, layer->parent->srid); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "srid"); if (a) { if (!layer->srid) layer->srid = list_explode_str(',', (char *) a); else { l = list_explode_str(',', (char *) a); list_add_list(layer->srid, l); list_free(l); } xmlFree(a); } /* Inherits from layer parent and replaces with specified value if defined */ a = xmlTextReaderGetAttribute(r, (xmlChar *) "geobbox"); if (a) { layer->geobbox = ows_geobbox_init(); ows_geobbox_set_from_str(o, layer->geobbox, (char *) a); xmlFree(a); } else if (!a && layer->parent && layer->parent->geobbox) { layer->geobbox = ows_geobbox_copy(layer->parent->geobbox); } else xmlFree(a); /* Inherits from layer parent and replaces with specified value if defined */ a = xmlTextReaderGetAttribute(r, (xmlChar *) "ns_prefix"); if (a) { buffer_add_str(layer->ns_prefix, (char *) a); xmlFree(a); } else if (!a && layer->parent && layer->parent->ns_prefix) { buffer_copy(layer->ns_prefix, layer->parent->ns_prefix); } else xmlFree(a); /* Inherits from layer parent and replaces with specified value if defined */ a = xmlTextReaderGetAttribute(r, (xmlChar *) "ns_uri"); if (a) { buffer_add_str(layer->ns_uri, (char *) a); xmlFree(a); } else if (!a && layer->parent && layer->parent->ns_uri) { buffer_copy(layer->ns_uri, layer->parent->ns_uri); } else xmlFree(a); a = xmlTextReaderGetAttribute(r, (xmlChar *) "exclude_items"); if (a) { layer->exclude_items = list_explode_str_trim(',', (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "include_items"); if (a) { layer->include_items = list_explode_str_trim(',', (char *) a); xmlFree(a); } a = xmlTextReaderGetAttribute(r, (xmlChar *) "pkey"); if (a) { layer->pkey = buffer_init(); buffer_add_str(layer->pkey, (char *) a); xmlFree(a); } ows_layer_list_add(o->layers, layer); }
/* * Set a geobbox matching a layer's extent */ ows_geobbox *ows_geobbox_compute(ows * o, buffer * layer_name) { double xmin, ymin, xmax, ymax; buffer *sql; PGresult *res; ows_geobbox *g; ows_bbox *bb; list *geom; list_node *ln; bool first = true; assert(o); assert(layer_name); sql = buffer_init(); geom = ows_psql_geometry_column(o, layer_name); assert(geom); g = ows_geobbox_init(); xmin = ymin = xmax = ymax = 0.0; for (ln = geom->first; ln ; ln = ln->next) { buffer_add_str(sql, "SELECT ST_xmin(g), ST_ymin(g), ST_xmax(g), ST_ymax(g) FROM "); if (o->estimated_extent) { buffer_add_str(sql, "(SELECT ST_Transform(ST_SetSRID(ST_Estimated_Extent('"); buffer_copy(sql, ows_psql_schema_name(o, layer_name)); buffer_add_str(sql, "','"); buffer_copy(sql, ows_psql_table_name(o, layer_name)); buffer_add_str(sql, "','"); buffer_copy(sql, ln->value); buffer_add_str(sql, "'), (SELECT ST_SRID(\""); buffer_copy(sql, ln->value); buffer_add_str(sql, "\") FROM "); buffer_copy(sql, ows_psql_schema_name(o, layer_name)); buffer_add_str(sql, ".\""); buffer_copy(sql, ows_psql_table_name(o, layer_name)); buffer_add_str(sql, "\" LIMIT 1)) ,4326) AS g) AS foo"); } else { buffer_add_str(sql, "(SELECT ST_Transform(ST_SetSRID(ST_Extent(\""); buffer_copy(sql, ln->value); buffer_add_str(sql, "\"), (SELECT ST_SRID(\""); buffer_copy(sql, ln->value); buffer_add_str(sql, "\") FROM "); buffer_copy(sql, ows_psql_schema_name(o, layer_name)); buffer_add_str(sql, ".\""); buffer_copy(sql, ows_psql_table_name(o, layer_name)); buffer_add_str(sql, "\" LIMIT 1)), 4326) AS g "); buffer_add_str(sql, " FROM "); buffer_copy(sql, ows_psql_schema_name(o, layer_name)); buffer_add_str(sql, ".\""); buffer_copy(sql, ows_psql_table_name(o, layer_name)); buffer_add_str(sql, "\" ) AS foo"); } res = ows_psql_exec(o, sql->buf); buffer_empty(sql); if (PQresultStatus(res) != PGRES_TUPLES_OK) { PQclear(res); buffer_free(sql); return g; } if (first || atof(PQgetvalue(res, 0, 0)) < xmin) xmin = atof(PQgetvalue(res, 0, 0)); if (first || atof(PQgetvalue(res, 0, 1)) < ymin) ymin = atof(PQgetvalue(res, 0, 1)); if (first || atof(PQgetvalue(res, 0, 2)) > xmax) xmax = atof(PQgetvalue(res, 0, 2)); if (first || atof(PQgetvalue(res, 0, 3)) > ymax) ymax = atof(PQgetvalue(res, 0, 3)); first = false; PQclear(res); } buffer_free(sql); bb = ows_bbox_init(); ows_bbox_set(o, bb, xmin, ymin, xmax, ymax, 4326); ows_geobbox_set_from_bbox(o, g, bb); ows_bbox_free(bb); return g; }