예제 #1
0
def features(ds, crs=None, encoding=None):
    fs = []

    for n in range(ds.GetLayerCount()):
        layer = ds.GetLayer(n)
        layer_name = layer.GetName()

        for feature in layer:
            atts = {}
            for k in range(feature.GetFieldCount()):
                fdef = feature.GetFieldDefnRef(k)
                name = fdef.GetName()
                type_val = _value(feature, k, fdef, encoding)
                if type_val:
                    atts[name] = gws.Attribute(name=name, type=type_val[0], value=type_val[1])

            uid = feature.GetFID()
            if not uid and 'fid' in atts:
                uid = atts.pop('fid').value

            fs.append(gws.gis.feature.Feature(
                uid=uid,
                category=layer_name,
                shape=_shape(feature.GetGeomFieldRef(0), crs),
                attributes=list(atts.values())
            ))

    return fs
예제 #2
0
def _f_FeatureInfoResponse(el: gws.XmlElement, fallback_crs, **kwargs):
    # esri
    #
    # <FeatureInfoResponse...
    #     <fields objectid="15111" shape="polygon"...
    #     <fields objectid="15111" shape="polygon"...

    if not xml2.element_is(el, 'GetFeatureInfoResponse'):
        return None

    features = []

    for field_el in xml2.all(el, 'Fields'):
        atts = []
        uid = ''

        for k, v in field_el.attributes:
            if k.lower() == 'objectid':
                uid = v
            else:
                atts.append(gws.Attribute(name=k, value=v))

        features.append(gws.gis.feature.from_args(uid=uid, attributes=atts))

    return features
예제 #3
0
 def save(self, collection_uid: str, fprops: gws.lib.feature.Props):
     f = gws.lib.feature.from_props(fprops)
     f.attributes.append(
         gws.Attribute(
             name=self.link_col,
             value=collection_uid,
         ))
     f.attributes.append(
         gws.Attribute(
             name=self.type_col,
             value=self.type,
         ))
     if str(f.uid).isdigit():
         fs = self.db.edit_operation('update', self.table, [f])
     else:
         f.uid = None
         fs = self.db.edit_operation('insert', self.table, [f])
     return fs[0]
예제 #4
0
def make_features(name, geom_type, columns, crs, xy, rows, cols, gap):
    features = []

    sx, sy = xy

    for r in range(rows):
        for c in range(cols):
            uid = r * cols + (c + 1)

            atts = []

            for k, v in columns.items():
                val = ''
                if v == 'int':
                    val = uid * 100
                if v == 'float':
                    val = uid * 200.0
                if v in ('varchar', 'text'):
                    val = f"{name}/{uid}"
                if v == 'date':
                    val = datetime.datetime(
                        2019, 1, 1) + datetime.timedelta(days=uid - 1)
                atts.append(gws.Attribute(name=k, value=val))

            x = sx + c * gap
            y = sy + r * gap

            geom = None

            if geom_type == 'point':
                geom = {'type': 'Point', 'coordinates': [x, y]}

            if geom_type == 'square':
                w = h = gap / 2
                geom = {
                    'type':
                    'Polygon',
                    'coordinates': [[
                        [x, y],
                        [x + w, y],
                        [x + w, y + h],
                        [x, y + h],
                        [x, y],
                    ]]
                }

            features.append(
                gws.gis.feature.from_props(
                    gws.Data(uid=uid,
                             attributes=atts,
                             shape={
                                 'crs': crs,
                                 'geometry': geom
                             } if geom else None)))

    return features
예제 #5
0
 def apply_to_dict(self, attr_values):
     return [
         gws.Attribute(
             title=r.title,
             name=r.name,
             value=self._apply_rule(r, attr_values),
             type=r.type,
             editable=r.editable,
         ) for r in self.rules
     ]
예제 #6
0
    def _find(self,
              req,
              p: FindFlurstueckParams,
              soft_limit=0,
              hard_limit=0) -> types.FindFlurstueckResult:

        fq = types.FindFlurstueckQuery(p)

        eigentuemer_flag = self._eigentuemer_flag(req, p)
        if eigentuemer_flag == _EF_FAIL:
            self._log_eigentuemer_access(req, p, is_ok=False)
            raise gws.base.web.error.BadRequest()

        fq.withEigentuemer = eigentuemer_flag == _EF_ALLOW
        fq.withBuchung = self._can_read_buchung(req.user)

        if p.get('shapes'):
            shape = gws.gis.shape.union(
                [gws.gis.shape.from_props(s) for s in p.get('shapes')])
            if shape:
                fq.shape = shape.transformed_to(self.provider.crs)

        if soft_limit:
            fq.limit = soft_limit

        fq.bblattMode = self.ui.get('bblattSearchMode', 'any')

        res = self.provider.find_flurstueck(fq)

        gws.log.debug(
            f'FS_SEARCH ef={eigentuemer_flag} query={p!r} total={res.total!r} len={len(res.features)}'
        )

        if hard_limit and res.total > hard_limit:
            raise gws.base.web.error.Conflict()

        project = req.require_project(p.projectUid)
        crs = p.get('crs') or project.map.crs

        for f in res.features:
            f.transform_to(crs)
            f.attributes.append(
                gws.Attribute(name='is_guest_user', value=req.user.is_guest))

        if fq.withEigentuemer:
            self._log_eigentuemer_access(req,
                                         p,
                                         is_ok=True,
                                         total=res.total,
                                         features=res.features)

        return res
예제 #7
0
def _f_GetFeatureInfoResponse(el: gws.XmlElement, fallback_crs, **kwargs):
    # geoserver/qgis
    #
    # <GetFeatureInfoResponse>
    #      <Layer name="....">
    #          <Feature id="...">
    #              <Attribute name="..." value="..."/>
    #              <Attribute name="geometry" value="<wkt>"/>

    if not xml2.element_is(el, 'GetFeatureInfoResponse'):
        return None

    features = []

    for layer_el in xml2.all(el, 'Layer'):

        layer_name = xml2.attr(layer_el, 'name')

        for feature_el in xml2.all(layer_el, 'Feature'):

            uid = xml2.attr(feature_el, 'id', 'fid')
            atts = []
            shape = None

            for attr_el in xml2.all(feature_el, 'Attribute'):
                name = xml2.attr(attr_el, 'name')
                value = xml2.attr(attr_el, 'value')

                if value == 'null':
                    continue

                if name.lower() == 'geometry':
                    try:
                        shape = gws.gis.shape.from_wkt(value, fallback_crs)
                    except Exception:
                        gws.log.exception()
                        continue

                if name.lower() in {'id', 'uid', 'fid'}:
                    uid = value
                    continue

                atts.append(gws.Attribute(name=name, value=value))

            features.append(
                gws.gis.feature.from_args(uid=uid,
                                          category=layer_name or '',
                                          shape=shape,
                                          attributes=atts))

    return features
예제 #8
0
def _fc_walk(el: gws.XmlElement, path, atts, shapes, fallback_crs):
    path = (path + _DEEP_PROP_NAME_DELIMITER + el.name) if path else el.name

    if not el.children and el.text:
        atts.append(gws.Attribute(name=path, value=el.text))
        return

    if gws.gis.gml.element_is_gml(el):
        shapes.append(gws.gis.gml.parse_to_shape(el,
                                                 fallback_crs=fallback_crs))
        return

    if xml2.element_is(el, 'boundedBy'):
        return

    for c in el.children:
        _fc_walk(c, path, atts, shapes, fallback_crs)
예제 #9
0
    def __init__(self,
                 uid,
                 attributes=None,
                 category=None,
                 elements=None,
                 shape=None,
                 style=None):
        super().__init__()
        self.attributes = []
        self.category = category or ''
        self.data_model = None
        self.elements = {}
        self.layer = None
        self.shape = None
        self.style = None
        self.templates = None
        self.uid = ''

        if isinstance(uid, str) and _COMBINED_UID_DELIMITER in uid:
            uid = uid.split(_COMBINED_UID_DELIMITER)[-1]

        self.uid = gws.to_str(uid)

        if attributes:
            if isinstance(attributes, dict):
                attributes = [
                    gws.Attribute({
                        'name': k,
                        'value': v
                    }) for k, v in attributes.items()
                ]
            self.attributes = attributes

        if elements:
            self.elements = elements

        if shape:
            if isinstance(shape, gws.gis.shape.Shape):
                self.shape = shape
            else:
                self.shape = gws.gis.shape.from_props(shape)

        if style:
            self.style = gws.lib.style.from_props(gws.Props(style))
예제 #10
0
    def api_save_data(self, req: gws.IWebRequest,
                      p: SaveDataParams) -> SaveDataResponse:
        tbl = self._get_table(p.tableUid)
        if not tbl:
            raise gws.base.web.error.NotFound()

        upd_features = []
        ins_features = []

        for rec in p.records:
            atts = []
            uid = None

            for a, v in zip(p.attributes, rec):
                if v is None or v == '':
                    continue
                atts.append(gws.Attribute(name=a.name, value=v))
                if a.name == tbl.table.key_column:
                    uid = v

            f = gws.lib.feature.from_props(
                gws.lib.feature.Props(uid=uid, attributes=atts))
            if uid:
                upd_features.append(f)
            else:
                ins_features.append(f)

        if ins_features and not tbl.with_add:
            # @TODO: this must be done in the dataModel
            raise gws.base.web.error.Forbidden()

        if upd_features:
            self.db.edit_operation('update', tbl.table, upd_features)
        if ins_features:
            self.db.edit_operation('insert', tbl.table, ins_features)

        return SaveDataResponse()
예제 #11
0
    def api_load_data(self, req: gws.IWebRequest,
                      p: LoadDataParams) -> LoadDataResponse:
        tbl = self._get_table(p.tableUid)
        if not tbl:
            raise gws.base.web.error.NotFound()

        features = self.db.select(
            gws.SqlSelectArgs(table=tbl.table,
                              sort=tbl.sort,
                              extra_where=['true']))

        attributes = [
            gws.Attribute(
                name=r.name,
                title=r.title,
                type=r.type,
                editable=r.editable,
            ) for r in tbl.data_model.rules
        ]

        records = []

        for f in features:
            f.apply_data_model(tbl.data_model)
            attr_dict = f.attr_dict
            records.append([attr_dict.get(a.name) for a in attributes])

        return LoadDataResponse(
            tableUid=tbl.uid,
            key=tbl.table.key_column,
            attributes=attributes,
            records=records,
            widths=tbl.widths or None,
            withFilter=tbl.with_filter,
            withAdd=tbl.with_add,
            withDelete=tbl.with_delete,
        )