Exemplo n.º 1
0
def _all_person(conn: AlkisConnection):
    dat = conn.data_schema

    rs = conn.select_from_ax('ax_anschrift', [
        'gml_id', 'ort_post', 'ortsteil', 'postleitzahlpostzustellung',
        'strasse', 'hausnummer', 'telefon'
    ])

    anschrift = {r['gml_id']: gws.compact(r) for r in rs}
    person = {}

    anrede = {1000: 'Frau', 2000: 'Herr', 3000: 'Firma'}

    rs = conn.select_from_ax('ax_person', [
        'gml_id', 'anrede', 'akademischergrad', 'geburtsdatum',
        'nachnameoderfirma', 'vorname', 'hat'
    ])

    for r in rs:
        hat = r.pop('hat', None) or []
        for h in hat:
            if h in anschrift:
                r['anschrift'] = anschrift[h]
                break
        r['anrede'] = anrede.get(r['anrede'])
        person[r['gml_id']] = gws.compact(r)

    return person
Exemplo n.º 2
0
def _all_buchungsblatt(conn: AlkisConnection):
    persons = _all_person(conn)
    blatts = {}

    rs = conn.select_from_ax('ax_buchungsblatt')

    for r in rs:
        bb = {
            'gml_id':
            r['gml_id'],
            'buchungsblattkennzeichen':
            r['buchungsblattkennzeichen'],
            'buchungsblattnummermitbuchstabenerweiterung':
            r['buchungsblattnummermitbuchstabenerweiterung'],
            'eigentuemer': [],
        }
        bb.update(resolver.places(conn, r))
        bb.update(resolver.attributes(conn, 'ax_buchungsblatt', r))
        blatts[r['gml_id']] = gws.compact(bb)

    rs = conn.select_from_ax('ax_namensnummer')

    for r in rs:
        if r['istbestandteilvon'] in blatts:
            eigentuemer = {
                'anteil': _anteil(r),
                'gml_id': r['gml_id'],
                'laufendenummernachdin1421': r['laufendenummernachdin1421'],
                'person': persons.get(r['benennt'])
            }
            eigentuemer.update(resolver.attributes(conn, 'ax_namensnummer', r))
            blatts[r['istbestandteilvon']]['eigentuemer'].append(
                gws.compact(eigentuemer))

    return blatts
Exemplo n.º 3
0
    def walk(sl: gws.SourceLayer, depth: int):
        if exclude_slf and gws.gis.source.layer_matches(sl, exclude_slf):
            return None

        cfg = None

        if not sl.is_group:
            # leaf layer
            cfg = leaf_layer_config_fn([sl])

        elif flatten and sl.a_level >= flatten.level:
            # flattened group layer
            # NB use the absolute level to compute flatness, could also use relative (=depth)
            if flatten.useGroups:
                cfg = leaf_layer_config_fn([sl])
            else:
                slf = gws.gis.source.LayerFilter(is_image=True)
                image_layers = gws.gis.source.filter_layers([sl], slf)
                if not image_layers:
                    return None
                cfg = leaf_layer_config_fn(image_layers)

        else:
            # ordinary group layer
            sub_cfgs = gws.compact(walk(sub, depth + 1) for sub in sl.layers)
            if not sub_cfgs:
                return None
            cfg = {
                'type': 'group',
                'uid': gws.to_uid(sl.name),
                'layers': sub_cfgs
            }

        if not cfg:
            return

        cfg = gws.merge(
            cfg, {
                'uid': gws.to_uid(sl.name),
                'title': sl.title,
                'clientOptions': {
                    'visible': sl.is_visible,
                    'expanded': sl.is_expanded,
                },
                'opacity': sl.opacity or 1,
            })

        if sl.scale_range:
            cfg['zoom'] = {
                'minScale': sl.scale_range[0],
                'maxScale': sl.scale_range[1],
            }

        for flt, cc in zip(custom_filters, custom_configs):
            if gws.gis.source.layer_matches(sl, flt):
                cfg = gws.deep_merge(vars(cc), cfg)
            cfg.pop('applyTo', None)

        return gws.compact(cfg)
Exemplo n.º 4
0
def _map_layer_tree(el: gws.XmlElement, map_layers):
    visible = el.attributes.get('checked') != 'Qt::Unchecked'
    expanded = el.attributes.get('expanded') == '1'

    if el.name == 'layer-tree-group':
        title = el.attributes.get('name')
        # qgis doesn't write 'id' for groups but our generators might
        name = el.attributes.get('id') or title

        sl = gws.SourceLayer(title=title, name=name)
        sl.metadata = gws.lib.metadata.from_args(title=title, name=name)

        sl.is_visible = visible
        sl.is_expanded = expanded
        sl.is_group = True
        sl.is_queryable = False
        sl.is_image = False

        sl.layers = gws.compact(
            _map_layer_tree(c, map_layers) for c in el.children)
        return sl

    if el.name == 'layer-tree-layer':
        sl = map_layers.get(el.attributes.get('id'))
        if sl:
            sl.is_visible = visible
            sl.is_expanded = expanded
            sl.is_group = False
            sl.is_image = True
            return sl
Exemplo n.º 5
0
def _metadata_dict(el: gws.XmlElement) -> dict:
    if not el:
        return {}

    d = {
        'abstract':
        xml2.text(el, 'Abstract'),
        'accessConstraints':
        xml2.text(el, 'AccessConstraints'),
        'attribution':
        xml2.text(el, 'Attribution Title'),
        'fees':
        xml2.text(el, 'Fees'),
        'keywords':
        xml2.text_list(el, 'Keywords', 'KeywordList', deep=True),
        'name':
        xml2.text(el, 'Name') or xml2.text(el, 'Identifier'),
        'title':
        xml2.text(el, 'Title'),
        'metaLinks':
        gws.compact(_parse_link(e) for e in xml2.all(el, 'MetadataURL')),
    }

    e = xml2.first(el, 'AuthorityURL')
    if e:
        d['authorityUrl'] = _parse_url(e)
        d['authorityName'] = xml2.attr(e, 'name')

    e = xml2.first(el, 'Identifier')
    if e:
        d['authorityIdentifier'] = e.text

    return gws.strip(d)
Exemplo n.º 6
0
def _combine_outputs(
        lros: t.List[gws.LegendRenderOutput],
        options: dict = None) -> t.Optional[gws.LegendRenderOutput]:
    imgs = gws.compact(to_image(lro) for lro in lros)
    img = _combine_images(imgs, options)
    if not img:
        return None
    return gws.LegendRenderOutput(image=img, size=img.size)
Exemplo n.º 7
0
 def walk(sl, parent_path, level):
     if not sl:
         return
     sl.a_uid = gws.to_uid(sl.name or sl.metadata.get('title'))
     sl.a_path = parent_path + '/' + sl.a_uid
     sl.a_level = level
     sl.layers = gws.compact(
         walk(c, sl.a_path, level + 1) for c in (sl.layers or []))
     return sl
Exemplo n.º 8
0
def _add_font_atts(atts, sv, prefix=''):
    font_name = _font_name(sv, prefix)
    font_size = sv.get(prefix + 'font_size') or DEFAULT_FONT_SIZE

    atts.update(
        gws.compact({
            'font-family': font_name.split('-')[0],
            'font-size': f'{font_size}px',
            'font-weight': sv.get(prefix + 'font_weight'),
            'font-style': sv.get(prefix + 'font_style'),
        }))
Exemplo n.º 9
0
def _layouts(root_el: gws.XmlElement):
    tpls = []

    for layout_el in xml2.all(root_el, 'Layouts Layout'):
        tpl = PrintTemplate(
            title=layout_el.attributes.get('name', ''),
            attributes=layout_el.attributes,
            index=len(tpls),
            elements=[],
        )
        pc_el = xml2.first(layout_el, 'PageCollection')
        if pc_el:
            tpl.elements.extend(
                gws.compact(_layout_element(c) for c in pc_el.children))
        tpl.elements.extend(
            gws.compact(_layout_element(c) for c in layout_el.children))

        tpls.append(tpl)

    return tpls
Exemplo n.º 10
0
def render(legend: gws.Legend,
           context: dict = None) -> t.Optional[gws.LegendRenderOutput]:
    if legend.path:
        img = gws.lib.image.from_path(legend.path)
        return gws.LegendRenderOutput(image=img, size=img.size)

    if legend.urls:
        lros = []

        for url in legend.urls:
            try:
                res = gws.gis.ows.request.get_url(url,
                                                  max_age=legend.cache_max_age)
                if not res.content_type.startswith('image/'):
                    raise gws.gis.ows.error.Error(
                        f'wrong content type {res.content_type!r}')
                img = gws.lib.image.from_bytes(res.content)
                lro = gws.LegendRenderOutput(image=img, size=img.size)
                lros.append(lro)
            except gws.gis.ows.error.Error:
                gws.log.exception(
                    f'render_legend: download failed url={url!r}')

        # NB even if there's only one image, it's not a bad idea to run it through the image converter
        return _combine_outputs(gws.compact(lros), legend.options)

    if legend.template:
        # @TODO return html legends as html
        res = legend.template.render(
            gws.TemplateRenderInput(context=context,
                                    out_mime=gws.lib.mime.PNG))
        img = gws.lib.image.from_path(res.path)
        return gws.LegendRenderOutput(image=img, size=img.size)

    if legend.layers:
        lros = gws.compact(
            la.render_legend_with_cache(context) for la in legend.layers
            if la.has_legend)
        return _combine_outputs(lros, legend.options)

    return None
Exemplo n.º 11
0
def check_layers(layers) -> t.List[gws.SourceLayer]:
    def walk(sl, parent_path, level):
        if not sl:
            return
        sl.a_uid = gws.to_uid(sl.name or sl.metadata.get('title'))
        sl.a_path = parent_path + '/' + sl.a_uid
        sl.a_level = level
        sl.layers = gws.compact(
            walk(c, sl.a_path, level + 1) for c in (sl.layers or []))
        return sl

    return gws.compact(walk(sl, '', 1) for sl in layers)
Exemplo n.º 12
0
    def _legend_layers(self, kwargs):
        if 'layers' in kwargs:
            user = self.tri.user or self.tpl.root.application.auth.guest_user
            return gws.compact(
                user.acquire('gws.ext.layer', uid)
                for uid in kwargs['layers'].split())

        if not self.tri.maps:
            return

        if 'map' in kwargs:
            mp = self.tri.maps[int(kwargs['map'])]
            return mp.visible_layers

        return self.tri.maps[0].visible_layers
Exemplo n.º 13
0
def _all_buchungsstelle(conn: AlkisConnection):
    blatts = _all_buchungsblatt(conn)
    stellen = {}

    rs = conn.select_from_ax('ax_buchungsstelle')

    for r in rs:
        bb = blatts.get(r['istbestandteilvon'], {})
        st = {
            'gml_id': r['gml_id'],
            'beginnt': r['beginnt'],
            'endet': r['endet'],
            'laufendenummer': r['laufendenummer'],
            'an': r['an'],
            'eigentuemer': bb.get('eigentuemer', []),
            'buchungsblatt':
            {k: v
             for k, v in bb.items() if k != 'eigentuemer'},
            'anteil': _anteil(r),
        }
        st.update(resolver.places(conn, r))
        st.update(resolver.attributes(conn, 'ax_buchungsstelle', r))
        stellen[r['gml_id']] = gws.compact(st)

    # resolve 'an' dependencies
    # Eine 'Buchungsstelle' verweist mit 'an' auf eine andere 'Buchungsstelle' auf einem anderen Buchungsblatt.
    # Die Buchungsstelle kann ein Recht (z.B. Erbbaurecht) oder einen Miteigentumsanteil 'an' der anderen Buchungsstelle haben
    # Die Relation zeigt stets vom begünstigten Recht zur belasteten Buchung
    # (z.B. Erbbaurecht hat ein Recht 'an' einem Grundstück).

    for r in stellen.values():
        for gml_id in r.get('an', []):
            if gml_id is None:
                continue
            if gml_id not in stellen:
                gws.log.warn(f'invalid "an" reference: {gml_id!r}')
                continue
            target = stellen[gml_id]
            if '_an' not in target:
                target['_an'] = []
            target['_an'].append(r['gml_id'])

    data = []
    for r in stellen.values():
        ls = _make_list(stellen, r, set())
        data.append({'gml_id': r['gml_id'], 'stellen': indexer.to_json(ls)})

    return data
Exemplo n.º 14
0
    def mapproxy_config(self, mc):
        m0 = self.tile_matrix_set.matrices[0]
        res = [
            units.scale_to_res(m.scale)
            for m in self.tile_matrix_set.matrices
        ]

        grid_uid = mc.grid(gws.compact({
            'origin': 'nw',  # nw = upper-left for WMTS
            'bbox': m0.extent,
            'res': res,
            'srs': self.source_crs.epsg,
            'tile_size': [m0.tile_width, m0.tile_height],
        }))

        src = self.mapproxy_back_cache_config(mc, self.get_tile_url(), grid_uid)
        self.mapproxy_layer_config(mc, src)
Exemplo n.º 15
0
    def leaf_layer_config(self, source_layers):
        default = {
            'type': 'qgisflat',
            '_provider': self,
            '_source_layers': source_layers
        }

        if len(source_layers) > 1 or source_layers[0].is_group:
            return default

        sl = source_layers[0]
        ds = sl.data_source
        prov = ds.get('provider')

        if prov not in self.direct_render:
            return default

        if prov == 'wms':
            layers = ds.get('layers')
            if not layers:
                return
            return {
                'type': 'wmsflat',
                'sourceLayers': {
                    'names': ds['layers']
                },
                'url': self.make_wms_url(ds['url'], ds['params']),
            }

        if prov == 'wmts':
            layers = ds.get('layers')
            if not layers:
                return
            return gws.compact({
                'type':
                'wmts',
                'url':
                ds['url'].split('?')[0],
                'sourceLayer':
                ds['layers'][0],
                'sourceStyle': (ds['options'] or {}).get('styles'),
            })

        gws.log.warn(f'directRender not supported for {prov!r}')
        return default
Exemplo n.º 16
0
    def find_features(self, req: gws.IWebRequest, p: Params) -> Response:
        """Perform a search"""

        project = req.require_project(p.projectUid)

        bounds = gws.Bounds(
            crs=p.crs or project.map.crs,
            extent=p.bbox or project.map.extent,
        )

        limit = self.limit
        if p.limit:
            limit = min(int(p.limit), self.limit)

        shapes = []
        if p.shapes:
            shapes = [gws.gis.shape.from_props(s) for s in p.shapes]

        tolerance = None
        if p.tolerance:
            tolerance = gws.lib.units.parse(p.tolerance,
                                            default=gws.lib.units.PX)

        args = gws.SearchArgs(
            bounds=bounds,
            keyword=(p.keyword or '').strip(),
            layers=gws.compact(
                req.acquire('gws.ext.layer', uid) for uid in p.layerUids),
            limit=limit,
            project=project,
            resolution=p.resolution,
            shapes=shapes,
            tolerance=tolerance,
        )

        found = runner.run(req, args)

        for f in found:
            # @TODO only pull specified props from a feature
            f.transform_to(args.bounds.crs)
            f.apply_templates()
            f.apply_data_model()

        return Response(
            features=[gws.props(f, req.user, context=self) for f in found])
Exemplo n.º 17
0
    def mapproxy_config(self, mc, options=None):
        # we use {x} like in Ol, mapproxy wants %(x)s
        url = re.sub(r'{([xyz])}', r'%(\1)s', self.url)

        grid_uid = mc.grid(
            gws.compact({
                'origin':
                self.service.origin,
                'bbox':
                self.service.extent,
                # 'res': res,
                'srs':
                self.service.crs.epsg,
                'tile_size': [self.service.tile_size, self.service.tile_size],
            }))

        src = self.mapproxy_back_cache_config(mc, url, grid_uid)
        self.mapproxy_layer_config(mc, src)
Exemplo n.º 18
0
def _parse_datasource(provider, source):
    if provider == 'wfs':
        params = _parse_datasource_uri(source)
        url = params.pop('url', '')
        if not url:
            return {}
        p = gws.lib.net.parse_url(url)
        typename = params.pop('typename', '') or p.params.get('typename')
        return {'url': url, 'typeName': typename, 'params': params}

    if provider == 'wms':
        options = {}
        for k, v in urllib.parse.parse_qs(source).items():
            options[k] = v[0] if len(v) < 2 else v

        layers = []
        if 'layers' in options:
            layers = options.pop('layers')
            # 'layers' must be a list
            if isinstance(layers, str):
                layers = [layers]

        url = options.pop('url', '')
        params = {}
        if url:
            url, params = _parse_url_with_qs(url)

        d = {
            'url': url,
            'options': options,
            'params': params,
            'layers': layers
        }
        if 'tileMatrixSet' in options:
            d['provider'] = 'wmts'
        return d

    if provider in ('gdal', 'ogr'):
        return {'path': source}

    if provider == 'postgres':
        return gws.compact(_parse_datasource_uri(source))

    return {'source': source}
Exemplo n.º 19
0
    def layer_caps_tree(self, rd: Request) -> LayerCapsTree:
        """Return the root layer caps for a project."""

        def enum(layer_uid, ancestors):
            layer: gws.ILayer = rd.req.acquire('gws.ext.layer', layer_uid)
            if not layer:
                return

            opts = self._layer_options(layer, level=len(ancestors) + 1)
            if not opts:
                return

            lc = LayerCaps()
            lc.ancestors = ancestors + [lc]

            if not layer.layers:
                self._populate_layer_caps(lc, layer, opts, [])
                tree.leaves.append(lc)
                return lc

            ch = gws.compact(enum(la.uid, lc.ancestors) for la in layer.layers)
            if ch:
                self._populate_layer_caps(lc, layer, opts, ch)
                return lc

        tree = LayerCapsTree(leaves=[], roots=[])

        if not rd.project:
            return tree

        if not self.root_layer_uid:
            tree.roots = gws.compact(enum(la.uid, []) for la in rd.project.map.layers)
            return tree

        uid = self.root_layer_uid
        if '.' not in uid:
            uid = rd.project.map.uid + '.' + uid
        root = enum(uid, [])
        if root:
            tree.roots.append(root)
        return tree
Exemplo n.º 20
0
        def enum(layer_uid, ancestors):
            layer: gws.ILayer = rd.req.acquire('gws.ext.layer', layer_uid)
            if not layer:
                return

            opts = self._layer_options(layer, level=len(ancestors) + 1)
            if not opts:
                return

            lc = LayerCaps()
            lc.ancestors = ancestors + [lc]

            if not layer.layers:
                self._populate_layer_caps(lc, layer, opts, [])
                tree.leaves.append(lc)
                return lc

            ch = gws.compact(enum(la.uid, lc.ancestors) for la in layer.layers)
            if ch:
                self._populate_layer_caps(lc, layer, opts, ch)
                return lc
Exemplo n.º 21
0
    def mapproxy_config(self, mc, options=None):
        layers = [sl.name for sl in self.source_layers if sl.name]
        if not self.var('capsLayersBottomUp'):
            layers = reversed(layers)

        args = self.provider.operation_args(gws.OwsVerb.GetMap)

        req = gws.merge(args['params'], {
            'transparent': True,
            'layers': ','.join(layers),
            'url': args['url'],
        })

        source_uid = mc.source(
            gws.compact({
                'type': 'wms',
                'supported_srs': [self.source_crs.epsg],
                'concurrent_requests': self.var('maxRequests'),
                'req': req
            }))

        self.mapproxy_layer_config(mc, source_uid)
Exemplo n.º 22
0
def _collect_gebs(conn):
    rs = conn.select_from_ax('ax_gebaeude', [
        'gml_id', 'gebaeudefunktion', 'weiteregebaeudefunktion', 'name',
        'bauweise', 'anzahlderoberirdischengeschosse',
        'anzahlderunterirdischengeschosse', 'hochhaus', 'objekthoehe',
        'dachform', 'zustand', 'geschossflaeche', 'grundflaeche',
        'umbauterraum', 'lagezurerdoberflaeche', 'dachart',
        'dachgeschossausbau', 'description', 'art', 'individualname',
        'baujahr', 'wkb_geometry'
    ])

    gebs = []

    for r in rs:
        r = gws.compact(r)
        r.update(resolver.attributes(conn, 'ax_gebaeude', r))
        gebs.append({
            'gml_id': r.pop('gml_id'),
            'geom': r.pop('wkb_geometry'),
            'attributes': indexer.to_json(r)
        })

    return gebs
Exemplo n.º 23
0
    def mapproxy_back_cache_config(self, mc, url, grid_uid):
        source_uid = mc.source({
            'type':
            'tile',
            'url':
            url,
            'grid':
            grid_uid,
            'concurrent_requests':
            self.var('maxRequests', default=0)
        })

        return mc.cache(
            gws.compact({
                'sources': [source_uid],
                'grids': [grid_uid],
                'cache': {
                    'type': 'file',
                    'directory_layout': 'mp'
                },
                'disable_storage': True,
                'format': self.image_format,
            }))
Exemplo n.º 24
0
    def mapproxy_layer_config(self, mc, source_uid):

        mc.layer({'name': self.uid + '_NOCACHE', 'sources': [source_uid]})

        res = [r for r in self.resolutions if r]
        if len(res) < 2:
            res = [res[0], res[0]]

        self.grid_uid = mc.grid(
            gws.compact({
                'origin': self.grid.origin,
                'tile_size': [self.grid.tileSize, self.grid.tileSize],
                'res': res,
                'srs': self.map.crs.epsg,
                'bbox': self.extent,
            }))

        meta_size = self.grid.reqSize or 4

        front_cache_config = {
            'sources': [source_uid],
            'grids': [self.grid_uid],
            'cache': {
                'type': 'file',
                'directory_layout': 'mp'
            },
            'meta_size': [meta_size, meta_size],
            'meta_buffer': self.grid.reqBuffer,
            'disable_storage': not self.has_cache,
            'minimize_meta_requests': True,
            'format': self.image_format,
        }

        self.cache_uid = mc.cache(front_cache_config)

        mc.layer({'name': self.uid, 'sources': [self.cache_uid]})
Exemplo n.º 25
0
def shape_to_fragment(shape: gws.IShape,
                      view: gws.MapView,
                      style: gws.IStyle = None,
                      label: str = None) -> t.List[gws.XmlElement]:
    if not shape:
        return []

    geom = t.cast(gws.gis.shape.Shape, shape).geom
    if geom.is_empty:
        return []

    trans = gws.gis.render.map_view_transformer(view)
    geom = shapely.ops.transform(trans, geom)

    if not style:
        return [_geometry(geom)]

    sv = style.values
    with_geometry = sv.with_geometry == 'all'
    with_label = label and _is_label_visible(view, sv)
    gt = _geom_type(geom)

    text = None
    if with_label:
        extra_y_offset = 0
        if sv.label_offset_y is None:
            if gt == _TYPE_POINT:
                extra_y_offset = 12
            if gt == _TYPE_LINESTRING:
                extra_y_offset = 6
        text = _label(geom, label, sv, extra_y_offset)

    marker = None
    marker_id = None
    if with_geometry and sv.marker:
        marker_id = '_M' + gws.random_string(8)
        marker = _marker(marker_id, sv)

    icon = None
    atts: dict = {}
    if with_geometry and sv.icon:
        res = _parse_icon(sv.icon, view.dpi)
        if res:
            el, w, h = res
            x, y, w, h = _icon_size_position(geom, sv, w, h)
            atts = {
                'x': f'{int(x)}',
                'y': f'{int(y)}',
                'width': f'{int(w)}',
                'height': f'{int(h)}',
            }
            icon = xml2.element(name=el.name,
                                attributes=gws.merge(el.attributes, atts),
                                children=el.children)

    body = None
    if with_geometry:
        _add_paint_atts(atts, sv)
        if marker:
            atts['marker-start'] = atts['marker-mid'] = atts[
                'marker-end'] = f'url(#{marker_id})'
        if gt == _TYPE_POINT or gt == _TYPE_MULTIPOINT:
            atts['r'] = (sv.point_size or DEFAULT_POINT_SIZE) // 2
        if gt == _TYPE_LINESTRING or gt == _TYPE_MUTLILINESTRING:
            atts['fill'] = 'none'
        body = _geometry(geom, atts)

    return gws.compact([marker, body, icon, text])
Exemplo n.º 26
0
def _layer_tree_configuration(
    source_layers: t.List[gws.SourceLayer],
    roots_slf: gws.gis.source.LayerFilter,
    exclude_slf: gws.gis.source.LayerFilter,
    flatten: FlattenOption,
    custom_configs: t.List[types.CustomConfig],
    leaf_layer_config_fn: t.Callable,
) -> t.List[gws.Config]:
    ##

    def walk(sl: gws.SourceLayer, depth: int):
        if exclude_slf and gws.gis.source.layer_matches(sl, exclude_slf):
            return None

        cfg = None

        if not sl.is_group:
            # leaf layer
            cfg = leaf_layer_config_fn([sl])

        elif flatten and sl.a_level >= flatten.level:
            # flattened group layer
            # NB use the absolute level to compute flatness, could also use relative (=depth)
            if flatten.useGroups:
                cfg = leaf_layer_config_fn([sl])
            else:
                slf = gws.gis.source.LayerFilter(is_image=True)
                image_layers = gws.gis.source.filter_layers([sl], slf)
                if not image_layers:
                    return None
                cfg = leaf_layer_config_fn(image_layers)

        else:
            # ordinary group layer
            sub_cfgs = gws.compact(walk(sub, depth + 1) for sub in sl.layers)
            if not sub_cfgs:
                return None
            cfg = {
                'type': 'group',
                'uid': gws.to_uid(sl.name),
                'layers': sub_cfgs
            }

        if not cfg:
            return

        cfg = gws.merge(
            cfg, {
                'uid': gws.to_uid(sl.name),
                'title': sl.title,
                'clientOptions': {
                    'visible': sl.is_visible,
                    'expanded': sl.is_expanded,
                },
                'opacity': sl.opacity or 1,
            })

        if sl.scale_range:
            cfg['zoom'] = {
                'minScale': sl.scale_range[0],
                'maxScale': sl.scale_range[1],
            }

        for flt, cc in zip(custom_filters, custom_configs):
            if gws.gis.source.layer_matches(sl, flt):
                cfg = gws.deep_merge(vars(cc), cfg)
            cfg.pop('applyTo', None)

        return gws.compact(cfg)

    ##

    custom_filters = [
        gws.gis.source.layer_filter_from_config(cc.applyTo)
        for cc in custom_configs
    ]

    # by default, take top-level layers as roots

    roots = gws.gis.source.filter_layers(
        source_layers, roots_slf or gws.gis.source.LayerFilter(level=1))

    # make configs...

    return gws.compact(walk(sl, 0) for sl in roots)
Exemplo n.º 27
0
def _sanitize(el: gws.XmlElement) -> t.Optional[gws.XmlElement]:
    if el.name in _ALLOWED_TAGS:
        return xml2.element(el.name, _sanitize_atts(el.attributes),
                            gws.compact(_sanitize(c) for c in el.children))
Exemplo n.º 28
0
def sanitize_element(el: gws.XmlElement) -> t.Optional[gws.XmlElement]:
    children = gws.compact(_sanitize(c) for c in el.children)
    if children:
        return xml2.tag('svg', _sanitize_atts(el.attributes), *children)