diff --git a/src/layman/layer/db/__init__.py b/src/layman/layer/db/__init__.py index 453244092..ed0bf23c3 100644 --- a/src/layman/layer/db/__init__.py +++ b/src/layman/layer/db/__init__.py @@ -258,7 +258,7 @@ def get_number_of_features(schema, table_name, conn_cur=None): return rows[0][0] -def get_text_data(schema, table_name, conn_cur=None): +def get_text_data(schema, table_name, primary_key, conn_cur=None): _, cur = conn_cur or db_util.get_connection_cursor() col_names = get_text_column_names(schema, table_name, conn_cur=conn_cur) if len(col_names) == 0: @@ -270,11 +270,12 @@ def get_text_data(schema, table_name, conn_cur=None): statement = sql.SQL(""" select {fields} from {table} -order by ogc_fid +order by {primary_key} limit {limit} """).format( fields=sql.SQL(',').join([sql.Identifier(col) for col in col_names]), table=sql.Identifier(schema, table_name), + primary_key=sql.Identifier(primary_key), limit=sql.Literal(limit), ) try: @@ -297,8 +298,8 @@ def get_text_data(schema, table_name, conn_cur=None): return col_texts, limit -def get_text_languages(schema, table_name, *, conn_cur=None): - texts, num_rows = get_text_data(schema, table_name, conn_cur) +def get_text_languages(schema, table_name, primary_key, *, conn_cur=None): + texts, num_rows = get_text_data(schema, table_name, primary_key, conn_cur) all_langs = set() for text in texts: # skip short texts @@ -312,61 +313,61 @@ def get_text_languages(schema, table_name, *, conn_cur=None): return sorted(list(all_langs)) -def get_most_frequent_lower_distance_query(schema, table_name): +def get_most_frequent_lower_distance_query(schema, table_name, primary_key): query = sql.SQL(""" with t1 as ( select - row_number() over (partition by ogc_fid) AS dump_id, + row_number() over (partition by {primary_key}) AS dump_id, sub_view.* from ( SELECT - ogc_fid, (st_dump(wkb_geometry)).geom as geometry + {primary_key}, (st_dump(wkb_geometry)).geom as geometry FROM {table} ) sub_view -order by ST_NPoints(geometry), ogc_fid, dump_id +order by ST_NPoints(geometry), {primary_key}, dump_id limit 5000 ) , t2 as ( select - row_number() over (partition by ogc_fid, dump_id) AS ring_id, + row_number() over (partition by {primary_key}, dump_id) AS ring_id, sub_view.* from ( ( SELECT - dump_id, ogc_fid, ST_ExteriorRing((ST_DumpRings(geometry)).geom) as geometry + dump_id, {primary_key}, ST_ExteriorRing((ST_DumpRings(geometry)).geom) as geometry FROM t1 where st_geometrytype(geometry) = 'ST_Polygon' ) union all ( SELECT - dump_id, ogc_fid, geometry + dump_id, {primary_key}, geometry FROM t1 where st_geometrytype(geometry) = 'ST_LineString' ) ) sub_view -order by ST_NPoints(geometry), ogc_fid, dump_id, ring_id +order by ST_NPoints(geometry), {primary_key}, dump_id, ring_id limit 5000 ) , t2cumsum as ( select *, --ST_NPoints(geometry), - sum(ST_NPoints(geometry)) over (order by ST_NPoints(geometry), ogc_fid, dump_id, ring_id + sum(ST_NPoints(geometry)) over (order by ST_NPoints(geometry), {primary_key}, dump_id, ring_id rows between unbounded preceding and current row) as cum_sum_points from t2 ) , t3 as ( -SELECT ogc_fid, dump_id, ring_id, (ST_DumpPoints(st_transform(geometry, 4326))).* +SELECT {primary_key}, dump_id, ring_id, (ST_DumpPoints(st_transform(geometry, 4326))).* FROM t2cumsum where cum_sum_points < 50000 ) , t4 as MATERIALIZED ( - select t3.ogc_fid, t3.dump_id, t3.ring_id, t3.path[1] as point_idx, t3.geom as point1, t3p2.geom as point2 + select t3.{primary_key}, t3.dump_id, t3.ring_id, t3.path[1] as point_idx, t3.geom as point1, t3p2.geom as point2 from t3 - inner join t3 t3p2 on (t3.ogc_fid = t3p2.ogc_fid and + inner join t3 t3p2 on (t3.{primary_key} = t3p2.{primary_key} and t3.dump_id = t3p2.dump_id and t3.ring_id = t3p2.ring_id and t3.path[1] + 1 = t3p2.path[1]) ) , tdist as ( -SELECT ogc_fid, dump_id, ring_id, point_idx, +SELECT {primary_key}, dump_id, ring_id, point_idx, ST_DistanceSphere(point1, point2) as distance FROM t4 ) @@ -402,14 +403,15 @@ def get_most_frequent_lower_distance_query(schema, table_name): limit 1 """).format( table=sql.Identifier(schema, table_name), + primary_key=sql.Identifier(primary_key), ) return query -def get_most_frequent_lower_distance(schema, table_name, conn_cur=None): +def get_most_frequent_lower_distance(schema, table_name, primary_key, conn_cur=None): _, cur = conn_cur or db_util.get_connection_cursor() - query = get_most_frequent_lower_distance_query(schema, table_name) + query = get_most_frequent_lower_distance_query(schema, table_name, primary_key) # print(f"\nget_most_frequent_lower_distance v1\nusername={username}, layername={layername}") # print(query) @@ -448,8 +450,8 @@ def get_most_frequent_lower_distance(schema, table_name, conn_cur=None): ] -def guess_scale_denominator(schema, table_name, *, conn_cur=None): - distance = get_most_frequent_lower_distance(schema, table_name, conn_cur=conn_cur) +def guess_scale_denominator(schema, table_name, primary_key, *, conn_cur=None): + distance = get_most_frequent_lower_distance(schema, table_name, primary_key, conn_cur=conn_cur) log_sd_list = [math.log10(sd) for sd in SCALE_DENOMINATORS] if distance is not None: coef = 2000 if distance > 100 else 1000 diff --git a/src/layman/layer/db/db_test.py b/src/layman/layer/db/db_test.py index ae3721c17..3f677de9d 100644 --- a/src/layman/layer/db/db_test.py +++ b/src/layman/layer/db/db_test.py @@ -175,12 +175,12 @@ def test_data_language(boundary_table): col_names = db.get_text_column_names(workspace, table_name) assert set(col_names) == set(['featurecla', 'name', 'name_alt']) with layman.app_context(): - text_data, _ = db.get_text_data(workspace, table_name) + text_data, _ = db.get_text_data(workspace, table_name, settings.OGR_DEFAULT_PRIMARY_KEY) # print(f"num_rows={num_rows}") assert len(text_data) == 1 assert text_data[0].startswith(' '.join(['International boundary (verify)'] * 100)) with layman.app_context(): - langs = db.get_text_languages(workspace, table_name) + langs = db.get_text_languages(workspace, table_name, settings.OGR_DEFAULT_PRIMARY_KEY) assert langs == ['eng'] @@ -214,7 +214,7 @@ def test_data_language_roads(road_table): 'vym_tahy_p' ]) with layman.app_context(): - langs = db.get_text_languages(workspace, table_name) + langs = db.get_text_languages(workspace, table_name, settings.OGR_DEFAULT_PRIMARY_KEY) assert langs == ['cze'] @@ -226,7 +226,7 @@ def test_populated_places_table(populated_places_table): col_names = db.get_text_column_names(workspace, table_name) assert len(col_names) == 31 with layman.app_context(): - langs = db.get_text_languages(workspace, table_name) + langs = db.get_text_languages(workspace, table_name, settings.OGR_DEFAULT_PRIMARY_KEY) assert set(langs) == set(['chi', 'eng', 'rus']) @@ -238,7 +238,7 @@ def test_data_language_countries(country_table): col_names = db.get_text_column_names(workspace, table_name) assert len(col_names) == 63 with layman.app_context(): - langs = db.get_text_languages(workspace, table_name) + langs = db.get_text_languages(workspace, table_name, settings.OGR_DEFAULT_PRIMARY_KEY) assert set(langs) == set([ 'ara', 'ben', @@ -266,13 +266,13 @@ def test_data_language_countries2(country110m_table): # assert len(col_names) == 63 with layman.app_context(): table_name = db.get_table_name(workspace, layername) - langs = db.get_text_languages(workspace, table_name) + langs = db.get_text_languages(workspace, table_name, settings.OGR_DEFAULT_PRIMARY_KEY) assert set(langs) == set(['eng']) def guess_scale_denominator(workspace, layer): table_name = db.get_table_name(workspace, layer) - return db.guess_scale_denominator(workspace, table_name) + return db.guess_scale_denominator(workspace, table_name, settings.OGR_DEFAULT_PRIMARY_KEY) def test_guess_scale_denominator(country110m_table, country50m_table, country10m_table, diff --git a/src/layman/layer/micka/csw.py b/src/layman/layer/micka/csw.py index 0313a2e92..1fa0adaaf 100644 --- a/src/layman/layer/micka/csw.py +++ b/src/layman/layer/micka/csw.py @@ -143,11 +143,13 @@ def get_template_path_and_values(workspace, layername, http_method): table_name = table_uri.table conn_cur = db_util.create_connection_cursor(db_uri_str=table_uri.db_uri_str) try: - languages = db.get_text_languages(table_uri.schema, table_name, conn_cur=conn_cur) + languages = db.get_text_languages(table_uri.schema, table_name, table_uri.primary_key_column, + conn_cur=conn_cur) except LaymanError: languages = [] try: - scale_denominator = db.guess_scale_denominator(table_uri.schema, table_name, conn_cur=conn_cur) + scale_denominator = db.guess_scale_denominator(table_uri.schema, table_name, table_uri.primary_key_column, + conn_cur=conn_cur) except LaymanError: scale_denominator = None spatial_resolution = {