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
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
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]
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
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 ]
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
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
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)
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))
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()
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, )