/* * Set a given bbox matching a feature collection's outerboundaries * or a simple feature's outerboundaries * Bbox is set from a list containing one or several layer names * and optionnaly one or several WHERE SQL statement following each layer name */ ows_bbox *ows_bbox_boundaries(ows * o, list * from, list * where, ows_srs * srs) { ows_bbox *bb; buffer *sql; list *geom; list_node *ln_from, *ln_where, *ln_geom; PGresult *res; assert(o && from && where && srs); bb = ows_bbox_init(); if (from->size != where->size) return bb; sql = buffer_init(); /* Put into a buffer the SQL request calculating an extent */ buffer_add_str(sql, "SELECT ST_xmin(g.extent), ST_ymin(g.extent), ST_xmax(g.extent), ST_ymax(g.extent) FROM "); buffer_add_str(sql, "(SELECT ST_Extent(foo.the_geom) as extent FROM ( "); /* For each layer name or each geometry column, make an union between retrieved features */ for (ln_from = from->first, ln_where = where->first; ln_from; ln_from = ln_from->next, ln_where = ln_where->next) { geom = ows_psql_geometry_column(o, ln_from->value); for (ln_geom = geom->first ; ln_geom ; ln_geom = ln_geom->next) { buffer_add_str(sql, " (SELECT ST_Transform(\""); buffer_copy(sql, ln_geom->value); buffer_add_str(sql, "\"::geometry, "); buffer_add_int(sql, srs->srid); buffer_add_str(sql, ") AS \"the_geom\" FROM \""); buffer_copy(sql, ows_psql_schema_name(o, ln_from->value)); buffer_add_str(sql, "\".\""); buffer_copy(sql, ows_psql_table_name(o, ln_from->value)); buffer_add_str(sql, "\" "); buffer_copy(sql, ln_where->value); buffer_add_str(sql, ")"); if (ln_geom->next) buffer_add_str(sql, " UNION ALL "); } if (ln_from->next) buffer_add_str(sql, " UNION ALL "); } buffer_add_str(sql, " ) AS foo) AS g"); res = ows_psql_exec(o, sql->buf); buffer_free(sql); if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) != 4) { PQclear(res); return bb; } bb->xmin = strtod(PQgetvalue(res, 0, 0), NULL); bb->ymin = strtod(PQgetvalue(res, 0, 1), NULL); bb->xmax = strtod(PQgetvalue(res, 0, 2), NULL); bb->ymax = strtod(PQgetvalue(res, 0, 3), NULL); /* FIXME Error handling */ ows_srs_copy(bb->srs, srs); PQclear(res); return bb; }
/* * 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; }