Пример #1
0
def migrate_maps_on_wms_workspace():
    logger.info(f'    Starting - migrate maps json urls')
    query = f'''
    select  w.name,
            p.name
    from {db_schema}.publications p inner join
         {db_schema}.workspaces w on w.id = p.id_workspace
    where p.type = %s
    '''
    params = (MAP_TYPE, )
    publications = db_util.run_query(query, params)
    gs_url = layer_gs_util.get_gs_proxy_base_url()
    gs_url = gs_url if gs_url.endswith('/') else f"{gs_url}/"
    gs_wms_url_pattern = r'^' + re.escape(
        gs_url
    ) + r'(' + util.USERNAME_ONLY_PATTERN + r')' + r'(/(?:ows|wms|wfs).*)$'
    all_workspaces = workspaces.get_workspace_names()
    for (workspace, map) in publications:
        file_path = input_file.get_map_file(workspace, map)
        is_changed = False
        with open(file_path, 'r') as map_file:
            map_json_raw = json.load(map_file)
            map_json = input_file.unquote_urls(map_json_raw)
            for map_layer in map_json['layers']:
                layer_url = map_layer.get('url', None)
                if not layer_url:
                    continue
                match = re.match(gs_wms_url_pattern, layer_url)
                if not match:
                    continue
                layer_workspace = match.group(1)
                if not layer_workspace:
                    continue
                if layer_workspace not in all_workspaces:
                    logger.warning(
                        f'      Do not know workspace {layer_workspace} in map {workspace}.{map}. Not migrating this url.'
                    )
                    continue

                layer_wms_workspace = wms.get_geoserver_workspace(
                    layer_workspace)
                map_layer[
                    'url'] = f'{gs_url}{layer_wms_workspace}{match.group(2)}'
                is_changed = True
        if is_changed:
            logger.info(f'      Store new json for {workspace}.{map}')
            with open(file_path, 'w') as map_file:
                json.dump(map_json, map_file, indent=4)
    logger.info(f'    DONE - migrate maps json urls')
Пример #2
0
def find_maps_containing_layer(layer_workspace, layer_name):
    from layman.layer import LAYER_TYPE
    from layman.layer.geoserver import util as layer_gs_util
    from layman.map.filesystem import input_file as map_input_file
    from layman.map.util import find_maps_by_grep
    from layman.util import get_publication_info

    gs_url = layer_gs_util.get_gs_proxy_base_url()
    gs_url = gs_url if gs_url.endswith('/') else f"{gs_url}/"
    gs_domain = urlparse(gs_url).hostname

    layer_info = get_publication_info(layer_workspace, LAYER_TYPE, layer_name, context={'keys': ['wms']})
    layer_wms_workspace = layer_info.get('_wms', {}).get('workspace')

    # first rough filters
    url_pattern = fr'^\s*.?url.?:\s*.*{gs_domain}.*/geoserver(/({layer_workspace}|{layer_wms_workspace}))?/(ows|wms|wfs).*,\s*$'
    url_maps = find_maps_by_grep(url_pattern)
    layer_pattern = fr'^\s*.?(layers|LAYERS).?:\s*.*{layer_name}.*\s*$'
    layer_maps = find_maps_by_grep(layer_pattern)
    maps = url_maps.intersection(layer_maps)

    # verify layer for map
    gs_ows_url_pattern = fr'^{re.escape(gs_url)}(({layer_workspace}|{layer_wms_workspace})/)?(?:ows|wms|wfs).*$'
    result_maps = set()
    for workspace, map in maps:
        map_json_raw = map_input_file.get_map_json(workspace, map)
        map_json = map_input_file.unquote_urls(map_json_raw)

        for map_layer in map_json['layers']:
            layer_url = map_layer.get('url')
            if not layer_url:
                continue
            match = re.match(gs_ows_url_pattern, layer_url)
            if not match:
                continue
            map_layers = CaseInsensitiveDict(**map_layer.get('params', dict())).get('layers')
            layers = unquote(map_layers).split(',')
            if layer_name in layers or f'{layer_workspace}:{layer_name}' in layers or f'{layer_wms_workspace}:{layer_name}' in layers:
                result_maps.add((workspace, map))

    return result_maps
Пример #3
0
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
Пример #4
0
def map_json_to_operates_on(map_json,
                            operates_on_muuids_filter=None,
                            editor=None):
    # Either caller know muuids or wants filter by editor, never both at the same time
    assert not operates_on_muuids_filter or not editor
    unquote_urls(map_json)
    gs_url = get_gs_proxy_base_url()
    gs_url = gs_url if gs_url.endswith('/') else f"{gs_url}/"
    gs_wms_url_pattern = r'^' + re.escape(gs_url) + r'(' + USERNAME_ONLY_PATTERN + r')' + \
                         settings.LAYMAN_GS_WMS_WORKSPACE_POSTFIX + r'/(?:ows|wms|wfs).*$'
    layman_layer_names = []
    for map_layer in map_json['layers']:
        layer_url = map_layer.get('url', None)
        if not layer_url:
            continue
        # print(f"layer_url={layer_url}")
        match = re.match(gs_wms_url_pattern, layer_url)
        if not match:
            continue
        layer_username = match.group(1)
        if not layer_username:
            continue
        # print(f"layer_username={layer_username}")
        layer_names = [
            n for n in map_layer.get('params', {}).get('LAYERS', '').split(',')
            if len(n) > 0
        ]
        if not layer_names:
            continue
        for layername in layer_names:
            layman_layer_names.append((layer_username, layername))
    operates_on = []
    csw_url = settings.CSW_PROXY_URL
    for (layer_username, layername) in layman_layer_names:
        layer_md_info = get_publication_info(layer_username,
                                             LAYER_TYPE,
                                             layername,
                                             context={
                                                 'keys': [
                                                     'metadata',
                                                 ],
                                             })
        layer_muuid = layer_md_info.get('metadata', {}).get('identifier')
        if operates_on_muuids_filter is not None:
            if layer_muuid not in operates_on_muuids_filter:
                continue
            layer_wms_info = get_publication_info(layer_username,
                                                  LAYER_TYPE,
                                                  layername,
                                                  context={
                                                      'keys': [
                                                          'wms',
                                                      ],
                                                  })
        else:
            layer_wms_info = get_publication_info(layer_username,
                                                  LAYER_TYPE,
                                                  layername,
                                                  context={
                                                      'keys': [
                                                          'wfs',
                                                      ],
                                                      'actor_name': editor,
                                                  })
            if not (layer_muuid and layer_wms_info):
                continue
        layer_title = layer_wms_info['title']
        layer_csw_url = f"{csw_url}?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&OUTPUTSCHEMA=http://www.isotc211.org/2005/gmd&ID={layer_muuid}#_{layer_muuid}"
        operates_on.append({
            'xlink:title': layer_title,
            'xlink:href': layer_csw_url,
        })
    return operates_on
Пример #5
0
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