def assert_all_sources_bbox(workspace, layer, expected_bbox_3857, *, expected_native_bbox=None, expected_native_crs=None): with app.app_context(): info = layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'key': ['bounding_box', 'native_bounding_box', 'native_crs']}) bbox_3857 = tuple(info['bounding_box']) native_bbox = tuple(info['native_bounding_box']) native_crs = info['native_crs'] assert_same_bboxes(expected_bbox_3857, bbox_3857, 0.00001) if expected_native_bbox is not None: assert_same_bboxes(expected_native_bbox, native_bbox, 0) assert expected_native_crs == native_crs assert_wfs_bbox(workspace, layer, expected_bbox_3857) assert_wms_bbox(workspace, layer, expected_bbox_3857) if expected_native_bbox is not None: assert_wfs_bbox(workspace, layer, expected_native_bbox, expected_bbox_crs=expected_native_crs) assert_wms_bbox(workspace, layer, expected_native_bbox, expected_bbox_crs=expected_native_crs) with app.app_context(): expected_bbox_4326 = bbox_util.transform(expected_bbox_3857, crs_from=crs_def.EPSG_3857, crs_to=crs_def.EPSG_4326, ) md_comparison = get_workspace_layer_metadata_comparison(workspace, layer) csw_prefix = settings.CSW_PROXY_URL csw_src_key = get_source_key_from_metadata_comparison(md_comparison, csw_prefix) assert csw_src_key is not None prop_key = 'extent' md_props = md_comparison['metadata_properties'] assert md_props[prop_key]['equal'] is True, md_props[prop_key] assert md_props[prop_key]['equal_or_null'] is True, md_props[prop_key] csw_bbox_4326 = tuple(md_props[prop_key]['values'][csw_src_key]) assert_same_bboxes(expected_bbox_4326, csw_bbox_4326, 0.001)
def publish_layer_from_qgis(workspace, layer, description, title, *, geoserver_workspace=None): geoserver_workspace = geoserver_workspace or workspace store_name = wms.get_qgis_store_name(layer) info = layman_util.get_publication_info( workspace, LAYER_TYPE, layer, context={'keys': [ 'wms', 'native_crs', ]}) layer_capabilities_url = info['_wms']['qgis_capabilities_url'] crs = info['native_crs'] gs_util.create_wms_store(geoserver_workspace, settings.LAYMAN_GS_AUTH, store_name, layer_capabilities_url) bbox = get_layer_bbox(workspace, layer) lat_lon_bbox = bbox_util.transform(bbox, crs, crs_def.EPSG_4326) gs_util.post_wms_layer(geoserver_workspace, layer, store_name, title, description, bbox, crs, settings.LAYMAN_GS_AUTH, lat_lon_bbox=lat_lon_bbox)
def patch_after_feature_change( self, workspace, layer, ): if self.is_aborted(): raise AbortedException file_type = layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'keys': ['file']})['file']['file_type'] if file_type == settings.FILE_TYPE_VECTOR: bbox = geoserver.get_layer_bbox(workspace, layer) geoserver_workspace = wms.get_geoserver_workspace(workspace) info = layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'keys': ['style_type', 'native_crs', ], }) style_type = info['style_type'] crs = info['native_crs'] lat_lon_bbox = bbox_util.transform(bbox, crs, crs_def.EPSG_4326) if style_type == 'sld': gs_util.patch_feature_type(geoserver_workspace, layer, auth=settings.LAYMAN_GS_AUTH, bbox=bbox, crs=crs, lat_lon_bbox=lat_lon_bbox) elif style_type == 'qml': gs_util.patch_wms_layer(geoserver_workspace, layer, auth=settings.LAYMAN_GS_AUTH, bbox=bbox, crs=crs, lat_lon_bbox=lat_lon_bbox) elif file_type != settings.FILE_TYPE_RASTER: raise NotImplementedError(f"Unknown file type: {file_type}") wms.clear_cache(workspace) if self.is_aborted(): raise AbortedException
def get_template_path_and_values(username, mapname, http_method=None, actor_name=None): assert http_method in [ common.REQUEST_METHOD_POST, common.REQUEST_METHOD_PATCH ] uuid_file_path = get_publication_uuid_file(MAP_TYPE, username, mapname) publ_datetime = datetime.fromtimestamp(os.path.getmtime(uuid_file_path)) revision_date = datetime.now() map_json = get_map_json(username, mapname) operates_on = map_json_to_operates_on(map_json, editor=actor_name) publ_info = get_publication_info( username, MAP_TYPE, mapname, context={ 'keys': ['title', 'bounding_box', 'description'], }) bbox_3857 = publ_info.get('bounding_box') if bbox_util.is_empty(bbox_3857): bbox_3857 = settings.LAYMAN_DEFAULT_OUTPUT_BBOX extent = bbox_util.transform(tuple(bbox_3857), epsg_from=3857, epsg_to=4326) title = publ_info['title'] abstract = publ_info.get('description') md_language = next( iter( common_language.get_languages_iso639_2(' '.join([ title or '', abstract or '', ]))), None) prop_values = _get_property_values( username=username, mapname=mapname, uuid=get_map_uuid(username, mapname), title=title, abstract=abstract or None, publication_date=publ_datetime.strftime('%Y-%m-%d'), revision_date=revision_date.strftime('%Y-%m-%d'), md_date_stamp=date.today().strftime('%Y-%m-%d'), identifier=url_for('rest_workspace_map.get', workspace=username, mapname=mapname), identifier_label=mapname, extent=extent, epsg_codes=map_json_to_epsg_codes(map_json), md_organisation_name=None, organisation_name=None, operates_on=operates_on, md_language=md_language, ) if http_method == common.REQUEST_METHOD_POST: prop_values.pop('revision_date', None) template_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'record-template.xml') return template_path, prop_values
def assert_wfs_bbox(workspace, layer, expected_bbox): wfs_layer = f"{workspace}:{layer}" with app.app_context(): wfs_get_capabilities = wfs.get_wfs_proxy(workspace) wfs_bbox_4326 = wfs_get_capabilities.contents[wfs_layer].boundingBoxWGS84 with app.app_context(): wfs_bbox_3857 = bbox_util.transform(wfs_bbox_4326, 4326, 3857, ) assert_same_bboxes(expected_bbox, wfs_bbox_3857, 0.00001)
def assert_wfs_bbox(workspace, layer, expected_bbox, *, expected_bbox_crs='EPSG:3857'): wfs_layer = f"{workspace}:{layer}" with app.app_context(): wfs_get_capabilities = wfs.get_wfs_proxy(workspace) wfs_bbox_4326 = wfs_get_capabilities.contents[wfs_layer].boundingBoxWGS84 with app.app_context(): wfs_bbox = bbox_util.transform(wfs_bbox_4326, crs_from=crs_def.EPSG_4326, crs_to=expected_bbox_crs, ) assert_same_bboxes(expected_bbox, wfs_bbox, 0.00001)
def get_template_path_and_values(workspace, layername, http_method=None): assert http_method in [common.REQUEST_METHOD_POST, common.REQUEST_METHOD_PATCH] publ_info = get_publication_info(workspace, LAYER_TYPE, layername, context={ 'keys': ['title', 'bounding_box', 'description'], }) title = publ_info['title'] abstract = publ_info.get('description') bbox_3857 = publ_info.get('bounding_box') if bbox_util.is_empty(bbox_3857): bbox_3857 = settings.LAYMAN_DEFAULT_OUTPUT_BBOX extent = bbox_util.transform(tuple(bbox_3857), epsg_from=3857, epsg_to=4326) uuid_file_path = get_publication_uuid_file(LAYER_TYPE, workspace, layername) publ_datetime = datetime.fromtimestamp(os.path.getmtime(uuid_file_path)) revision_date = datetime.now() md_language = next(iter(common_language.get_languages_iso639_2(' '.join([ title or '', abstract or '' ]))), None) try: languages = db.get_text_languages(workspace, layername) except LaymanError: languages = [] try: scale_denominator = db.guess_scale_denominator(workspace, layername) except LaymanError: scale_denominator = None prop_values = _get_property_values( workspace=workspace, layername=layername, uuid=get_layer_uuid(workspace, layername), title=title, abstract=abstract or None, publication_date=publ_datetime.strftime('%Y-%m-%d'), revision_date=revision_date.strftime('%Y-%m-%d'), md_date_stamp=date.today().strftime('%Y-%m-%d'), identifier=url_for('rest_workspace_layer.get', workspace=workspace, layername=layername), identifier_label=layername, extent=extent, wms_url=wms.get_wms_url(workspace, external_url=True), wfs_url=wfs.get_wfs_url(workspace, external_url=True), md_organisation_name=None, organisation_name=None, md_language=md_language, languages=languages, scale_denominator=scale_denominator, epsg_codes=settings.LAYMAN_OUTPUT_SRS_LIST, ) if http_method == common.REQUEST_METHOD_POST: prop_values.pop('revision_date', None) template_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'record-template.xml') return template_path, prop_values
def assert_wms_bbox(workspace, layer, expected_bbox): with app.app_context(): wms_get_capabilities = wms.get_wms_proxy(workspace) wms_layer = wms_get_capabilities.contents[layer] bbox_3857 = next(bbox[:4] for bbox in wms_layer.crs_list if bbox[4] == 'EPSG:3857') assert_same_bboxes(expected_bbox, bbox_3857, 0.00001) with app.app_context(): expected_bbox_4326 = bbox_util.transform(expected_bbox, 3857, 4326, ) wgs84_bboxes = [bbox[:4] for bbox in wms_layer.crs_list if bbox[4] in ['EPSG:4326', 'CRS:84']] wgs84_bboxes.append(wms_layer.boundingBoxWGS84) for wgs84_bbox in wgs84_bboxes: assert_same_bboxes(expected_bbox_4326, wgs84_bbox, 0.00001)
def assert_wms_bbox(workspace, layer, expected_bbox, *, expected_bbox_crs='EPSG:3857'): with app.app_context(): wms_get_capabilities = wms.get_wms_proxy(workspace) wms_layer = wms_get_capabilities.contents[layer] bbox = next(bbox[:4] for bbox in wms_layer.crs_list if bbox[4] == expected_bbox_crs) assert_same_bboxes(expected_bbox, bbox, 0.00001) with app.app_context(): expected_bbox_4326 = bbox_util.transform(expected_bbox, crs_from=expected_bbox_crs, crs_to=crs_def.EPSG_4326, ) wgs84_bboxes = [bbox[:4] for bbox in wms_layer.crs_list if bbox[4] in [crs_def.EPSG_4326, crs_def.CRS_84]] wgs84_bboxes.append(wms_layer.boundingBoxWGS84) for wgs84_bbox in wgs84_bboxes: assert_same_bboxes(expected_bbox_4326, wgs84_bbox, 0.00001)
def publish_layer_from_db(workspace, layername, description, title, *, crs, geoserver_workspace=None): geoserver_workspace = geoserver_workspace or workspace bbox = get_layer_bbox(workspace, layername) lat_lon_bbox = bbox_util.transform(bbox, crs, crs_def.EPSG_4326) gs_util.post_feature_type(geoserver_workspace, layername, description, title, bbox, crs, settings.LAYMAN_GS_AUTH, lat_lon_bbox=lat_lon_bbox)
def assert_all_sources_bbox(workspace, layer, expected_bbox): with app.app_context(): bbox = tuple(layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'key': ['bounding_box']})['bounding_box']) assert_same_bboxes(expected_bbox, bbox, 0) assert_wfs_bbox(workspace, layer, expected_bbox) assert_wms_bbox(workspace, layer, expected_bbox) with app.app_context(): expected_bbox_4326 = bbox_util.transform(expected_bbox, 3857, 4326, ) md_comparison = get_workspace_layer_metadata_comparison(workspace, layer) csw_prefix = settings.CSW_PROXY_URL csw_src_key = get_source_key_from_metadata_comparison(md_comparison, csw_prefix) assert csw_src_key is not None prop_key = 'extent' md_props = md_comparison['metadata_properties'] assert md_props[prop_key]['equal'] is True, md_props[prop_key] assert md_props[prop_key]['equal_or_null'] is True, md_props[prop_key] csw_bbox_4326 = tuple(md_props[prop_key]['values'][csw_src_key]) assert_same_bboxes(expected_bbox_4326, csw_bbox_4326, 0.001)
def refresh_bbox( self, username, mapname, ): if self.is_aborted(): raise AbortedException mapjson = util.get_map_file_json(username, mapname) bbox_4326 = util.get_bbox_from_json(mapjson) bbox_3857 = bbox_util.transform(bbox_4326, 4326, 3857) set_bbox( username, MAP_TYPE, mapname, bbox_3857, ) if self.is_aborted(): raise AbortedException
def test_info(workspace, publ_type, publication): ensure_publication(workspace, publ_type, publication) headers = data.HEADERS.get( data.PUBLICATIONS[(workspace, publ_type, publication)][data.TEST_DATA].get( 'users_can_write', [None])[0]) with app.app_context(): info = process_client.get_workspace_publication( publ_type, workspace, publication, headers) asserts_rest.is_complete_in_rest(info) asserts_rest.mandatory_keys_in_rest(info) # Access rights all_auth_info = util.get_users_and_headers_for_publication( workspace, publ_type, publication) for right in ['read', 'write']: exp_list = all_auth_info[right][util.KEY_AUTH][util.KEY_EXP_LIST] assert set(exp_list) == set(info['access_rights'][right]) # Bounding box exp_bbox = data.PUBLICATIONS[(workspace, publ_type, publication)][data.TEST_DATA].get('bbox') if exp_bbox: info_bbox = info['bounding_box'] assert_util.assert_same_bboxes(info_bbox, exp_bbox, 0.01) file_type = data.PUBLICATIONS[( workspace, publ_type, publication)][data.TEST_DATA].get('file_type') if file_type == settings.FILE_TYPE_RASTER: native_bbox = gdal.get_bbox(workspace, publication) with app.app_context(): bbox_3857 = bbox_util.transform(native_bbox, info['native_crs'], crs_def.EPSG_3857) assert_util.assert_same_bboxes(bbox_3857, exp_bbox, 0.01)
def get_publication_infos_with_metainfo(workspace_name=None, pub_type=None, style_type=None, reader=None, writer=None, limit=None, offset=None, full_text_filter=None, bbox_filter=None, bbox_filter_crs=None, order_by_list=None, ordering_full_text=None, ordering_bbox=None, ordering_bbox_crs=None, ): order_by_list = order_by_list or [] full_text_tsquery = db_util.to_tsquery_string(full_text_filter) if full_text_filter else None full_text_like = '%' + full_text_filter + '%' if full_text_filter else None ordering_full_text_tsquery = db_util.to_tsquery_string(ordering_full_text) if ordering_full_text else None ordering_bbox_srid = db_util.get_srid(ordering_bbox_crs) filtering_bbox_srid = db_util.get_srid(bbox_filter_crs) where_params_def = [ (workspace_name, 'w.name = %s', (workspace_name,)), (pub_type, 'p.type = %s', (pub_type,)), (style_type, 'p.style_type::text = %s', (style_type,)), (reader and not is_user_with_name(reader), 'p.everyone_can_read = TRUE', tuple()), (is_user_with_name(reader), f"""(p.everyone_can_read = TRUE or (u.id is not null and w.name = %s) or EXISTS(select 1 from {DB_SCHEMA}.rights r inner join {DB_SCHEMA}.users u2 on r.id_user = u2.id inner join {DB_SCHEMA}.workspaces w2 on w2.id = u2.id_workspace where r.id_publication = p.id and r.type = 'read' and w2.name = %s))""", (reader, reader,)), (writer and not is_user_with_name(writer), 'p.everyone_can_write = TRUE', tuple()), (is_user_with_name(writer), f"""(p.everyone_can_write = TRUE or (u.id is not null and w.name = %s) or EXISTS(select 1 from {DB_SCHEMA}.rights r inner join {DB_SCHEMA}.users u2 on r.id_user = u2.id inner join {DB_SCHEMA}.workspaces w2 on w2.id = u2.id_workspace where r.id_publication = p.id and r.type = 'write' and w2.name = %s))""", (writer, writer,)), (full_text_filter, '(_prime_schema.my_unaccent(p.title) @@ to_tsquery(unaccent(%s))' 'or lower(unaccent(p.title)) like lower(unaccent(%s)))', (full_text_tsquery, full_text_like,)), (bbox_filter, 'ST_TRANSFORM(ST_SetSRID(p.bbox, p.srid), %s) && ST_MakeBox2D(ST_MakePoint(%s, %s), ST_MakePoint(%s, %s))', (filtering_bbox_srid, ) + bbox_filter if bbox_filter else None, ), ] order_by_definition = { consts.ORDER_BY_FULL_TEXT: ('ts_rank_cd(_prime_schema.my_unaccent(p.title), to_tsquery(unaccent(%s))) DESC', (ordering_full_text_tsquery,)), consts.ORDER_BY_TITLE: ("regexp_replace(lower(unaccent(p.title)), '[^a-zA-Z0-9 ]', '', 'g') ASC", tuple()), consts.ORDER_BY_LAST_CHANGE: ('updated_at DESC', tuple()), consts.ORDER_BY_BBOX: (""" -- A∩B / (A + B) CASE -- if there is any intersection WHEN ST_TRANSFORM(ST_SetSRID(p.bbox, p.srid), %s) && ST_SetSRID(ST_MakeBox2D(ST_MakePoint(%s, %s), ST_MakePoint(%s, %s)), %s) THEN -- in cases, when area of intersection is 0, we want it rank higher than no intersection GREATEST(st_area(st_intersection(ST_TRANSFORM(ST_SetSRID(p.bbox, p.srid), %s), ST_SetSRID(ST_MakeBox2D(ST_MakePoint(%s, %s), ST_MakePoint(%s, %s)), %s))), 0.00001) -- we have to solve division by 0 / (GREATEST(st_area(ST_TRANSFORM(ST_SetSRID(p.bbox, p.srid), %s)), 0.00001) + GREATEST(st_area(ST_SetSRID(ST_MakeBox2D(ST_MakePoint(%s, %s), ST_MakePoint(%s, %s)), %s)), 0.00001) ) -- if there is no intersection, result is 0 in all cases ELSE 0 END DESC """, (ordering_bbox_srid, ) + ordering_bbox + (ordering_bbox_srid, ) + (ordering_bbox_srid, ) + ordering_bbox + (ordering_bbox_srid, ) + (ordering_bbox_srid, ) + ordering_bbox + (ordering_bbox_srid, ) if ordering_bbox else tuple()), } assert all(ordering_item in order_by_definition.keys() for ordering_item in order_by_list) ######################################################### # SELECT clause select_clause = f""" select p.id as id_publication, w.name as workspace_name, p.type, p.name, p.title, p.uuid::text, p.style_type, p.updated_at, ST_XMIN(p.bbox) as xmin, ST_YMIN(p.bbox) as ymin, ST_XMAX(p.bbox) as xmax, ST_YMAX(p.bbox) as ymax, p.srid as srid, (select rtrim(concat(case when u.id is not null then w.name || ',' end, string_agg(w2.name, ',') || ',', case when p.everyone_can_read then %s || ',' end ), ',') from {DB_SCHEMA}.rights r inner join {DB_SCHEMA}.users u2 on r.id_user = u2.id inner join {DB_SCHEMA}.workspaces w2 on w2.id = u2.id_workspace where r.id_publication = p.id and r.type = 'read') can_read_users, (select rtrim(concat(case when u.id is not null then w.name || ',' end, string_agg(w2.name, ',') || ',', case when p.everyone_can_write then %s || ',' end ), ',') from {DB_SCHEMA}.rights r inner join {DB_SCHEMA}.users u2 on r.id_user = u2.id inner join {DB_SCHEMA}.workspaces w2 on w2.id = u2.id_workspace where r.id_publication = p.id and r.type = 'write') can_write_users, count(*) OVER() AS full_count from {DB_SCHEMA}.workspaces w inner join {DB_SCHEMA}.publications p on p.id_workspace = w.id left join {DB_SCHEMA}.users u on u.id_workspace = w.id """ select_params = (ROLE_EVERYONE, ROLE_EVERYONE, ) ######################################################### # WHERE clause where_params = tuple() where_parts = list() for (value, where_part, params, ) in where_params_def: if value: where_parts.append(where_part) where_params = where_params + params where_clause = '' if where_parts: where_clause = 'WHERE ' + '\n AND '.join(where_parts) + '\n' ######################################################### # ORDER BY clause order_by_params = tuple() order_by_parts = list() for order_by_part in order_by_list: order_by_parts.append(order_by_definition[order_by_part][0]) order_by_params = order_by_params + order_by_definition[order_by_part][1] order_by_parts.append('w.name ASC') order_by_parts.append('p.name ASC') order_by_clause = 'ORDER BY ' + ', '.join(order_by_parts) ######################################################### # Pagination clause pagination_params = tuple() pagination_clause = '' if limit is not None: assert limit >= 0 assert isinstance(limit, int) pagination_clause = pagination_clause + f' LIMIT {limit} ' if offset is not None: assert offset >= 0 assert isinstance(offset, int) pagination_clause = pagination_clause + f' OFFSET {offset} ' ######################################################### # Put it together sql_params = select_params + where_params + order_by_params + pagination_params select = select_clause + where_clause + order_by_clause + pagination_clause values = db_util.run_query(select, sql_params) # print(f'get_publication_infos:\n\nselect={select}\n\nsql_params={sql_params}\n\n&&&&&&&&&&&&&&&&&') infos = {(workspace_name, type, publication_name,): {'id': id_publication, 'name': publication_name, 'title': title, 'uuid': uuid, 'type': type, 'style_type': style_type, 'updated_at': updated_at, 'native_bounding_box': [xmin, ymin, xmax, ymax], 'native_crs': db_util.get_crs(srid) if srid else None, 'access_rights': {'read': can_read_users.split(','), 'write': can_write_users.split(',')} } for id_publication, workspace_name, type, publication_name, title, uuid, style_type, updated_at, xmin, ymin, xmax, ymax, srid, can_read_users, can_write_users, _ in values} infos = {key: {**value, 'bounding_box': list(bbox_util.transform(value['native_bounding_box'], value['native_crs'], DEFAULT_BBOX_CRS)) if value['native_bounding_box'][0] and value['native_crs'] and DEFAULT_BBOX_CRS != value['native_crs'] else value['native_bounding_box'], } for key, value in infos.items()} if values: total_count = values[0][-1] else: count_clause = f""" select count(*) AS full_count from {DB_SCHEMA}.workspaces w inner join {DB_SCHEMA}.publications p on p.id_workspace = w.id left join {DB_SCHEMA}.users u on u.id_workspace = w.id """ sql_params = where_params select = count_clause + where_clause count = db_util.run_query(select, sql_params) total_count = count[0][-1] if infos: start = offset + 1 if offset else 1 content_range = (start, start + len(infos) - 1) else: content_range = (0, 0) result = {'items': infos, 'total_count': total_count, 'content_range': content_range, } return result
def get_template_path_and_values(workspace, mapname, http_method=None, actor_name=None): assert http_method in [ common.REQUEST_METHOD_POST, common.REQUEST_METHOD_PATCH ] uuid_file_path = get_publication_uuid_file(MAP_TYPE, workspace, mapname) publ_datetime = datetime.fromtimestamp(os.path.getmtime(uuid_file_path)) revision_date = datetime.now() map_json = get_map_json(workspace, mapname) operates_on = map_json_to_operates_on(map_json, editor=actor_name) publ_info = get_publication_info( workspace, MAP_TYPE, mapname, context={ 'keys': ['title', 'native_bounding_box', 'description', 'native_crs'], }) native_bbox = publ_info.get('native_bounding_box') crs = publ_info.get('native_crs') if bbox_util.is_empty(native_bbox): native_bbox = crs_def.CRSDefinitions[crs].default_bbox extent = bbox_util.transform(native_bbox, crs_from=publ_info.get('native_crs'), crs_to=crs_def.EPSG_4326) title = publ_info['title'] abstract = publ_info.get('description') md_language = next( iter( common_language.get_languages_iso639_2(' '.join([ title or '', abstract or '', ]))), None) prop_values = _get_property_values( workspace=workspace, mapname=mapname, uuid=get_map_uuid(workspace, mapname), title=title, abstract=abstract or None, publication_date=publ_datetime.strftime('%Y-%m-%d'), revision_date=revision_date.strftime('%Y-%m-%d'), md_date_stamp=date.today().strftime('%Y-%m-%d'), identifier=url_for('rest_workspace_map.get', workspace=workspace, mapname=mapname), identifier_label=mapname, extent=extent, crs_list=[crs], md_organisation_name=None, organisation_name=None, operates_on=operates_on, md_language=md_language, ) if http_method == common.REQUEST_METHOD_POST: prop_values.pop('revision_date', None) template_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'record-template.xml') return template_path, prop_values
def refresh_wms( self, workspace, layername, store_in_geoserver, description=None, title=None, access_rights=None, ): info = layman_util.get_publication_info( workspace, LAYER_TYPE, layername, context={'keys': [ 'file', 'native_bounding_box', 'native_crs', ]}) file_type = info['file']['file_type'] crs = info['native_crs'] assert description is not None assert title is not None geoserver_workspace = wms.get_geoserver_workspace(workspace) geoserver.ensure_workspace(workspace) if self.is_aborted(): raise AbortedException coverage_store_name = wms.get_geotiff_store_name(layername) if file_type == settings.FILE_TYPE_VECTOR: if store_in_geoserver: gs_util.delete_wms_layer(geoserver_workspace, layername, settings.LAYMAN_GS_AUTH) gs_util.delete_wms_store(geoserver_workspace, settings.LAYMAN_GS_AUTH, wms.get_qgis_store_name(layername)) geoserver.publish_layer_from_db( workspace, layername, description, title, crs=crs, geoserver_workspace=geoserver_workspace, ) else: gs_util.delete_feature_type(geoserver_workspace, layername, settings.LAYMAN_GS_AUTH) geoserver.publish_layer_from_qgis( workspace, layername, description, title, geoserver_workspace=geoserver_workspace, ) elif file_type == settings.FILE_TYPE_RASTER: file_path = info['_file']['normalized_file']['gs_path'] real_bbox = info['native_bounding_box'] bbox = bbox_util.ensure_bbox_with_area(real_bbox, crs_def.CRSDefinitions[crs].no_area_bbox_padding)\ if not bbox_util.is_empty(real_bbox) else crs_def.CRSDefinitions[crs].default_bbox lat_lon_bbox = bbox_util.transform(bbox, crs, crs_def.EPSG_4326) gs_util.create_coverage_store(geoserver_workspace, settings.LAYMAN_GS_AUTH, coverage_store_name, file_path) gs_util.publish_coverage(geoserver_workspace, settings.LAYMAN_GS_AUTH, coverage_store_name, layername, title, description, bbox, crs, lat_lon_bbox=lat_lon_bbox) else: raise NotImplementedError(f"Unknown file type: {file_type}") geoserver.set_security_rules(workspace, layername, access_rights, settings.LAYMAN_GS_AUTH, geoserver_workspace) wms.clear_cache(workspace) if self.is_aborted(): wms.delete_layer(workspace, layername) raise AbortedException
def get_map_with_internal_layers_json(layers, *, native_extent=None, native_crs=None): if not native_extent: with app.app_context(): extents = [ layman_util.get_publication_info( workspace, process_client.LAYER_TYPE, layer, context={'keys': ['bounding_box']})['bounding_box'] for workspace, layer in layers ] native_extent = ( min([minx for minx, _, _, _ in extents]), min([miny for _, miny, _, _ in extents]), max([maxx for _, _, maxx, _ in extents]), max([maxy for _, _, _, maxy in extents]), ) native_crs = crs_def.EPSG_3857 assert native_crs with app.app_context(): extent_4326 = bbox.transform( native_extent, crs_from=native_crs, crs_to=crs_def.EPSG_4326, ) map_json = { "describedBy": "https://raw.githubusercontent.com/hslayers/map-compositions/2.0.0/schema.json", "schema_version": "2.0.0", "abstract": "Map generated for internal layers", "title": "Map of internal layers", "extent": extent_4326, "nativeExtent": native_extent, "projection": native_crs, "layers": [{ "metadata": {}, "visibility": True, "opacity": 1, "title": "Defini\u010dn\u00ed body administrativn\u00edch celk\u016f", "className": "HSLayers.Layer.WMS", "singleTile": True, "wmsMaxScale": 0, "legends": [ "https%3A%2F%2Fgeoportal.kraj-lbc.cz%2Fcgi-bin%2Fmapserv%3Fmap%3D%2Fdata%2Fgis%2FMapServer%2Fprojects%2Fwms%2Fatlas%2Fadministrativni_cleneni.map%26version%3D1.3.0%26service%3DWMS%26request%3DGetLegendGraphic%26sld_version%3D1.1.0%26layer%3Ddefinicni_body_administrativnich_celku%26format%3Dimage%2Fpng%26STYLE%3Ddefault" ], "maxResolution": None, "minResolution": 0, "url": "https%3A%2F%2Fgeoportal.kraj-lbc.cz%2Fcgi-bin%2Fmapserv%3Fmap%3D%2Fdata%2Fgis%2FMapServer%2Fprojects%2Fwms%2Fatlas%2Fadministrativni_cleneni.map%26", "params": { "LAYERS": "definicni_body_administrativnich_celku", "INFO_FORMAT": "application/vnd.ogc.gml", "FORMAT": "image/png", "FROMCRS": "EPSG:3857", "VERSION": "1.3.0" }, "dimensions": {} }] } gs_url = layer_gs_util.get_gs_proxy_base_url() gs_url = gs_url if gs_url.endswith('/') else f"{gs_url}/" for workspace, layer in layers: geoserver_workspace = geoserver_wms.get_geoserver_workspace(workspace) map_json['layers'].append({ "metadata": {}, "visibility": True, "opacity": 1, "title": layer, "className": "HSLayers.Layer.WMS", "singleTile": True, "url": f"{gs_url}{geoserver_workspace}/ows", "params": { "LAYERS": layer, "FORMAT": "image/png" } }) return map_json
def get_map_with_internal_layers_json(layers, *, extent_3857=None): if not extent_3857: with app.app_context(): extents = [layman_util.get_publication_info(workspace, process_client.LAYER_TYPE, layer, context={'keys': ['wms', 'bounding_box']})['bounding_box'] for workspace, layer in layers] extent_3857 = (min([minx for minx, _, _, _ in extents]), min([miny for _, miny, _, _ in extents]), max([maxx for _, _, maxx, _ in extents]), min([maxy for _, _, _, maxy in extents]), ) with app.app_context(): extent_4326 = bbox.transform(extent_3857, 3857, 4326) map_json = f''' {{ "abstract": "Map generated for internal layers", "title": "Map of internal layers", "extent": [ "{extent_4326[0]}", "{extent_4326[1]}", "{extent_4326[2]}", "{extent_4326[3]}" ], "projection": "epsg:3857", "layers": [ {{ "metadata": {{}}, "visibility": true, "opacity": 1, "title": "Defini\u010dn\u00ed body administrativn\u00edch celk\u016f", "className": "HSLayers.Layer.WMS", "singleTile": true, "wmsMaxScale": 0, "legends": [ "https%3A%2F%2Fgeoportal.kraj-lbc.cz%2Fcgi-bin%2Fmapserv%3Fmap%3D%2Fdata%2Fgis%2FMapServer%2Fprojects%2Fwms%2Fatlas%2Fadministrativni_cleneni.map%26version%3D1.3.0%26service%3DWMS%26request%3DGetLegendGraphic%26sld_version%3D1.1.0%26layer%3Ddefinicni_body_administrativnich_celku%26format%3Dimage%2Fpng%26STYLE%3Ddefault" ], "maxResolution": null, "minResolution": 0, "url": "https%3A%2F%2Fgeoportal.kraj-lbc.cz%2Fcgi-bin%2Fmapserv%3Fmap%3D%2Fdata%2Fgis%2FMapServer%2Fprojects%2Fwms%2Fatlas%2Fadministrativni_cleneni.map%26", "params": {{ "LAYERS": "definicni_body_administrativnich_celku", "INFO_FORMAT": "application/vnd.ogc.gml", "FORMAT": "image/png", "FROMCRS": "EPSG:3857", "VERSION": "1.3.0" }}, "dimensions": {{}} }} ''' gs_url = layer_gs_util.get_gs_proxy_base_url() gs_url = gs_url if gs_url.endswith('/') else f"{gs_url}/" for workspace, layer in layers: map_json = map_json + f''', {{ "metadata": {{}}, "visibility": true, "opacity": 1, "title": "{layer}", "className": "HSLayers.Layer.WMS", "singleTile": true, "url": "{gs_url}{workspace}/ows", "params": {{ "LAYERS": "{layer}", "FORMAT": "image/png" }} }}''' map_json = map_json + ''' ] }''' return map_json