def synthese_export_serialization(cls): """ Décorateur qui definit une serialisation particuliere pour la vue v_synthese_for_export Il rajoute la fonction as_dict_ordered qui conserve l'ordre des attributs tel que definit dans le model (fonctions utilisees pour les exports) et qui redefinit le nom des colonnes tel qu'ils sont nommes en configuration """ EXPORT_COLUMNS = current_app.config["SYNTHESE"]["EXPORT_COLUMNS"] # tab of cls attributes from EXPORT COLUMNS formated_default_columns = [key for key, value in EXPORT_COLUMNS.items()] # list of tuple (class attribute, serializer) cls_db_cols_and_serializer = [] # list of attributes of the class which are in the synthese export cnfig # use for generate shapefiles cls.db_cols = [] for key in formated_default_columns: # get the cls attribut: try: # get the class atribut from the syntese export config cls_attri = getattr(cls, key) # add in serialiser list if not cls_attri.type.__class__.__name__ == "Geometry": cls_db_cols_and_serializer.append(( cls_attri.key, SERIALIZERS.get(cls_attri.type.__class__.__name__.lower(), lambda x: x), )) # add in cls.db_cols cls.db_cols.append(cls_attri) # execpt if the attribute does not exist except AttributeError: pass def serialize_order_fn(self): order_dict = OrderedDict() for item, _serializer in cls_db_cols_and_serializer: order_dict.update( {EXPORT_COLUMNS.get(item): _serializer(getattr(self, item))}) return order_dict def serialize_geofn(self, geoCol, idCol): if not getattr(self, geoCol) is None: geometry = to_shape(getattr(self, geoCol)) else: geometry = {"type": "Point", "coordinates": [0, 0]} feature = Feature( id=str(getattr(self, idCol)), geometry=geometry, properties=self.as_dict_ordered(), ) return feature cls.as_dict_ordered = serialize_order_fn cls.as_geofeature_ordered = serialize_geofn return cls
def get_synthese_data(info_role): """ Return synthese and t_validations data filtered by form params Params must have same synthese fields names .. :quickref: Validation; Parameters: ------------ info_role (User): Information about the user asking the route. Auto add with kwargs Returns ------- dict { "data": FeatureCollection "nb_obs_limited": int est-ce que le nombre de données retournée est > au nb limites "nb_total": nb_total, } """ if request.json: filters = request.json elif request.data: # decode byte to str - compat python 3.5 filters = json.loads(request.data.decode("utf-8")) else: filters = { key: request.args.get(key) for key, value in request.args.items() } if "limit" in filters: result_limit = filters.pop("limit") else: result_limit = blueprint.config["NB_MAX_OBS_MAP"] # Construction de la requête select # Les champs correspondent aux champs obligatoires # + champs définis par l'utilisateur columns = (blueprint.config["COLUMNS_API_VALIDATION_WEB_APP"] + blueprint.config["MANDATORY_COLUMNS"]) select_columns = [] serializer = {} for c in columns: try: att = getattr(VSyntheseValidation, c) select_columns.append(att) serializer[c] = SERIALIZERS.get( att.type.__class__.__name__.lower(), lambda x: x) except AttributeError as error: log.warning("Validation : colonne {} inexistante".format(c)) # Construction de la requête avec SyntheseQuery # Pour profiter des opérations CRUVED query = (select(select_columns).where( VSyntheseValidation.the_geom_4326.isnot(None)).order_by( VSyntheseValidation.date_min.desc())) validation_query_class = SyntheseQuery(VSyntheseValidation, query, filters) validation_query_class.filter_query_all_filters(info_role) result = DB.engine.execute( validation_query_class.query.limit(result_limit)) # TODO nb_total factice nb_total = 0 geojson_features = [] properties = {} for r in result: properties = {k: serializer[k](r[k]) for k in serializer.keys()} properties["nom_vern_or_lb_nom"] = (r["nom_vern"] if r["nom_vern"] else r["lb_nom"]) geojson = ast.literal_eval(r["geojson"]) geojson["properties"] = properties geojson["id"] = r["id_synthese"] geojson_features.append(geojson) return { "data": FeatureCollection(geojson_features), "nb_obs_limited": nb_total == blueprint.config["NB_MAX_OBS_MAP"], "nb_total": nb_total, }