diff options
Diffstat (limited to 'webmap-cgi')
| -rwxr-xr-x | webmap-cgi | 47 | 
1 files changed, 40 insertions, 7 deletions
| @@ -60,7 +60,7 @@ def get_query_map(layernames : set[str]) -> dict[str,bytes]:      # pylint: disable-next=no-member      with PG_CONN.cursor(binary=True, scrollable=False, withhold=False) as cur:          for layername in layernames: -            cur.execute('SELECT f_geometry_column, coord_dimension ' +            cur.execute('SELECT f_geometry_column, coord_dimension, srid, type '                            'FROM ' + common.escape_identifier(SCHEMA_NAME) + '.geometry_columns '                            'WHERE f_table_schema = %s AND f_table_name = %s',                          params=(SCHEMA_NAME, layername), @@ -69,13 +69,35 @@ def get_query_map(layernames : set[str]) -> dict[str,bytes]:              if resp is None:                  continue              geom_cols = [ resp[0] ] -            force2d = resp[1] > 2 +            geom_dim = resp[1] +            force2d = geom_dim > 2 +            geom_type = resp[3] +            geom_srid = resp[2] +            if geom_srid != 3006: +                # If the SRS isn't projected and/or isn't in meter units then ST_Area() resp. +                # ST_Length() aren't in m² resp. m.  We could reproject, but since the target +                # SRS is SWEREF 99 we just warn on mismatch +                logging.warning('Geometry column "%s" in table "%s" has SRID %d != 3006', +                                geom_cols[0], layername, geom_srid) +            if geom_type in ('POLYGON', 'MULTIPOLYGON', +                             'POLYGONM', 'MULTIPOLYGONM'): +                d = 2 # surface +            elif geom_type in ('LINESTRING', 'MULTILINESTRING', +                               'LINESTRINGM', 'MULTILINESTRINGM'): +                d = 1 # curve +            elif geom_type in ('POINT', 'MULTIPOINT', +                               'POINTM', 'MULTIPOINTM'): +                d = 0 # point +            else: +                logging.warning('Geometry column "%s" in table "%s" has unknown type %s', +                                geom_cols[0], layername, geom_type) +                d = -1              resp = cur.fetchone()              if resp is not None:                  logging.warning('Table "%s" has multiple geometry colums, ' -                                'only considering "%s"', -                                layername, geom_cols[0]) +                                'only considering "%s" (%s, SRID=%d, dim=%d)', +                                layername, geom_cols[0], geom_type, geom_srid, geom_dim)                  while resp is not None:                      geom_cols.append( resp[0] )                      resp = cur.fetchone() @@ -109,9 +131,14 @@ def get_query_map(layernames : set[str]) -> dict[str,bytes]:                            'WHERE table_schema = %s AND table_name = %s',                          params=(SCHEMA_NAME, layername),                          prepare=False) +            # never empty since the we know the table exists and has a primary key              resp = cur.fetchone()              while resp is not None:                  c = resp[0] +                if (c in ('layer_group', 'layer') or +                        (d == 2 and c in ('geom_area', 'geom_perimeter')) or +                        (d == 1 and c == 'geom_length')): +                    logging.warning('Duplicate column name "%s"', c)                  if c != pkey_col and c not in geom_cols:                      column_names.append(c)                  resp = cur.fetchone() @@ -122,10 +149,16 @@ def get_query_map(layernames : set[str]) -> dict[str,bytes]:              for column_name in column_names:                  query +=     'm.' + common.escape_identifier(column_name) + ','              if force2d: -                query +=     'ST_Force2D(m.' + common.escape_identifier(geom_cols[0]) + ') ' -                query +=         'AS ' + common.escape_identifier(geom_cols[0]) + ',' +                geom_col2d_esc = 'ST_Force2D(m.' + common.escape_identifier(geom_cols[0]) + ')' +                query +=     geom_col2d_esc + ' AS ' + common.escape_identifier(geom_cols[0]) + ','              else: -                query +=     'm.' + common.escape_identifier(geom_cols[0]) + ',' +                geom_col2d_esc = 'm.' + common.escape_identifier(geom_cols[0]) +                query +=     geom_col2d_esc + ',' +            if d == 2: +                query +=     'ST_Area(' + geom_col2d_esc +') AS geom_area,' +                query +=     'ST_Perimeter(' + geom_col2d_esc +') AS geom_perimeter,' +            elif d == 1: +                query +=     'ST_Length(' + geom_col2d_esc +') AS geom_length,'              query +=         '%s AS layer_group,%s AS layer '              query +=      'FROM ' + common.escape_identifier(SCHEMA_NAME) + '.'              query +=                common.escape_identifier(layername) + ' m ' | 
