Changeset 195 for src/ows/ows_psql.c

Show
Ignore:
Timestamp:
01/21/10 22:19:43 (2 years ago)
Author:
ol
Message:

Use PostGIS 1.5 GeomFromGML to parse GML instead of TinyOWS one. Add check_schema and check_valid_geom config properties to allow to bypass schema and is_valid check, cf #44.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/ows/ows_psql.c

    r192 r195  
    434434 
    435435 
    436  
    437 /* 
    438  *  * Return the number of rows returned by the specified requests 
    439  *   */ 
     436/* 
     437 * Return the number of rows returned by the specified requests 
     438 */ 
    440439int ows_psql_number_features(ows * o, list * from, list * where) 
    441440{ 
    442         buffer *sql; 
    443         PGresult *res; 
    444         list_node *ln_from, *ln_where; 
    445         int nb; 
    446  
    447         assert(o != NULL); 
    448         assert(from != NULL); 
    449         assert(where != NULL); 
    450  
    451         nb = 0; 
    452  
    453         /* checks if from list and where list have the same size */ 
    454         if (from->size != where->size) return nb; 
    455  
    456  
    457         for (ln_from = from->first, ln_where = where->first; ln_from != NULL; 
    458                  ln_from = ln_from->next, ln_where = ln_where->next) { 
    459                  sql = buffer_init(); 
    460  
    461                  /* execute the request */ 
    462                  buffer_add_str(sql, "SELECT count(*) FROM \""); 
    463                  buffer_copy(sql, ln_from->value); 
    464                  buffer_add_str(sql, "\" "); 
    465                  buffer_copy(sql, ln_where->value); 
    466                  res = PQexec(o->pg, sql->buf); 
    467                  buffer_free(sql); 
    468  
    469                  if (PQresultStatus(res) != PGRES_TUPLES_OK) { 
    470                      PQclear(res); 
    471                      return -1; 
    472                  } 
    473                  nb = nb + atoi(PQgetvalue(res, 0, 0)); 
     441    buffer *sql; 
     442    PGresult *res; 
     443    list_node *ln_from, *ln_where; 
     444    int nb; 
     445 
     446    assert(o != NULL); 
     447    assert(from != NULL); 
     448    assert(where != NULL); 
     449 
     450    nb = 0; 
     451 
     452    /* checks if from list and where list have the same size */ 
     453    if (from->size != where->size) return nb; 
     454 
     455 
     456    for (ln_from = from->first, ln_where = where->first; ln_from != NULL; 
     457             ln_from = ln_from->next, ln_where = ln_where->next) { 
     458             sql = buffer_init(); 
     459 
     460             /* execute the request */ 
     461             buffer_add_str(sql, "SELECT count(*) FROM \""); 
     462             buffer_copy(sql, ln_from->value); 
     463             buffer_add_str(sql, "\" "); 
     464             buffer_copy(sql, ln_where->value); 
     465             res = PQexec(o->pg, sql->buf); 
     466             buffer_free(sql); 
     467 
     468             if (PQresultStatus(res) != PGRES_TUPLES_OK) { 
    474469                 PQclear(res); 
    475          } 
    476  
    477         return nb; 
    478 } 
     470                 return -1; 
     471             } 
     472             nb = nb + atoi(PQgetvalue(res, 0, 0)); 
     473             PQclear(res); 
     474     } 
     475 
     476    return nb; 
     477} 
     478 
     479 
     480static xmlNodePtr ows_psql_recursive_parse_gml(ows * o, xmlNodePtr n) 
     481{ 
     482    xmlNodePtr c; 
     483    static xmlNodePtr result=NULL; 
     484 
     485    assert(o != NULL); 
     486    assert(n != NULL); 
     487 
     488    if (result) return result;  /* avoid recursive loop */ 
     489 
     490    /* We are looking for the geometry part inside GML doc */ 
     491    for (; n ; n = n->next) { 
     492 
     493        if (n->type != XML_ELEMENT_NODE) continue; 
     494 
     495        /* GML SF Geometries Types */ 
     496        if (   !strcmp((char *) n->name, "Point") 
     497            || !strcmp((char *) n->name, "LineString") 
     498            || !strcmp((char *) n->name, "Curve") 
     499            || !strcmp((char *) n->name, "Polygon") 
     500            || !strcmp((char *) n->name, "Surface") 
     501            || !strcmp((char *) n->name, "MultiPoint") 
     502            || !strcmp((char *) n->name, "MultiLineString") 
     503            || !strcmp((char *) n->name, "MultiCurve") 
     504            || !strcmp((char *) n->name, "MultiPolygon") 
     505            || !strcmp((char *) n->name, "MultiSurface") 
     506            || !strcmp((char *) n->name, "MultiGeometry")) { 
     507 
     508            return n; 
     509        } 
     510        /* TODO Add check on namespace GML 3 and GML 3.2 */ 
     511 
     512        /* Recursive exploration */ 
     513        if (n->children) 
     514            for (c = n->children ; c ; c = c->next) 
     515                if ((result = ows_psql_recursive_parse_gml(o, c))) 
     516                    return result; 
     517    } 
     518 
     519    return NULL; 
     520} 
     521 
     522 
     523/* 
     524 * Transform a GML geometry to PostGIS EWKT 
     525 * Return NULL on error 
     526 */ 
     527buffer * ows_psql_gml_to_sql(ows * o, xmlNodePtr n) 
     528{ 
     529    PGresult *res; 
     530    xmlNodePtr g; 
     531    buffer *result, *sql, *gml; 
     532 
     533    assert(o != NULL); 
     534    assert(n != NULL); 
     535 
     536    g = ows_psql_recursive_parse_gml(o, n); 
     537    if (!g) return NULL;    /* No Geometry founded in GML doc */ 
     538 
     539    /* Retrieve the sub doc and launch GML parse via PostGIS */ 
     540    gml = buffer_init(); 
     541    cgi_add_xml_into_buffer(gml, g); 
     542     
     543    sql = buffer_init(); 
     544    buffer_add_str(sql, "SELECT ST_GeomFromGML('"); 
     545    buffer_add_str(sql, gml->buf); 
     546    buffer_add_str(sql, "')"); 
     547 
     548    res = PQexec(o->pg, sql->buf); 
     549    buffer_free(gml); 
     550 
     551 
     552    /* GML Parse errors cases */ 
     553    if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) != 1) { 
     554        buffer_free(sql); 
     555        PQclear(res); 
     556        return NULL; 
     557    } 
     558 
     559    result = buffer_init(); 
     560    buffer_add_str(result, PQgetvalue(res, 0, 0)); 
     561    PQclear(res); 
     562 
     563    /* Check if geometry is valid */ 
     564    if (o->check_valid_geom) { 
     565 
     566        buffer_empty(sql); 
     567        buffer_add_str(sql, "SELECT ST_IsValid('"); 
     568        buffer_add_str(sql, result->buf); 
     569        buffer_add_str(sql, "')"); 
     570 
     571        res = PQexec(o->pg, sql->buf); 
     572 
     573        if (   PQresultStatus(res) != PGRES_TUPLES_OK 
     574            || PQntuples(res) != 1 
     575            || (char) PQgetvalue(res, 0, 0)[0] !=  't') { 
     576            buffer_free(sql); 
     577            buffer_free(result); 
     578            PQclear(res); 
     579            return NULL; 
     580        } 
     581    } 
     582 
     583    buffer_free(sql); 
     584    PQclear(res); 
     585 
     586    return result; 
     587} 
     588 
    479589 
    480590/*