Krita Source Code Documentation
Loading...
Searching...
No Matches
KisMetaData::SmartMergeStrategy Class Reference

#include <kis_meta_data_merge_strategy_p.h>

+ Inheritance diagram for KisMetaData::SmartMergeStrategy:

Public Member Functions

QString description () const override
 
QString id () const override
 
void merge (Store *dst, QList< const Store * > srcs, QList< double > score) const override
 
QString name () const override
 
 SmartMergeStrategy ()
 
 ~SmartMergeStrategy () override
 

Protected Member Functions

Value election (QList< const Store * > srcs, QList< double > score, const QString &key) const
 
void mergeEntry (Store *dst, QList< const Store * > srcs, const Schema *schema, const QString &identifier) const
 

Detailed Description

Definition at line 50 of file kis_meta_data_merge_strategy_p.h.

Constructor & Destructor Documentation

◆ SmartMergeStrategy()

SmartMergeStrategy::SmartMergeStrategy ( )

Definition at line 148 of file kis_meta_data_merge_strategy_p.cc.

149{
150}

◆ ~SmartMergeStrategy()

SmartMergeStrategy::~SmartMergeStrategy ( )
override

Definition at line 152 of file kis_meta_data_merge_strategy_p.cc.

153{
154}

Member Function Documentation

◆ description()

QString SmartMergeStrategy::description ( ) const
overridevirtual
Returns
a description of this merge strategy

Implements KisMetaData::MergeStrategy.

Definition at line 165 of file kis_meta_data_merge_strategy_p.cc.

166{
167 return i18n("This merge strategy attempts to find the best solution for merging, "
168 "for instance by merging the list of authors together, or keeping "
169 "identical photographic information.");
170}

◆ election()

Value SmartMergeStrategy::election ( QList< const Store * > srcs,
QList< double > score,
const QString & key ) const
protected

Definition at line 177 of file kis_meta_data_merge_strategy_p.cc.

178{
179 QList<ScoreValue> scoreValues;
180 for (int i = 0; i < srcs.size(); i++) {
181 if (srcs[i]->containsEntry(key)) {
182 const Value& nv = srcs[i]->getEntry(key).value();
183 if (nv.type() != Value::Invalid) {
184 bool found = false;
185 for (int j = 0; j < scoreValues.size(); j++) {
186 ScoreValue& sv = scoreValues[j];
187 if (sv.value == nv) {
188 found = true;
189 sv.score += scores[i];
190 break;
191 }
192 }
193 if (!found) {
194 ScoreValue sv;
195 sv.score = scores[i];
196 sv.value = nv;
197 scoreValues.append(sv);
198 }
199 }
200 }
201 }
202 if (scoreValues.size() < 1) {
203 warnMetaData << "SmartMergeStrategy::election returned less than 1 score value";
204 return Value();
205 }
206 const ScoreValue* bestSv = 0;
207 double bestScore = -1.0;
208 Q_FOREACH (const ScoreValue& sv, scoreValues) {
209 if (sv.score > bestScore) {
210 bestScore = sv.score;
211 bestSv = &sv;
212 }
213 }
214 if (bestSv) {
215 return bestSv->value;
216 }
217 else {
218 return Value();
219 }
220}
#define warnMetaData
Definition kis_debug.h:103
ValueType type

References KisMetaData::Value::Invalid, ScoreValue::score, KisMetaData::Value::type(), ScoreValue::value, and warnMetaData.

◆ id()

QString SmartMergeStrategy::id ( ) const
overridevirtual
Returns
the id of this merge strategy

Implements KisMetaData::MergeStrategy.

Definition at line 156 of file kis_meta_data_merge_strategy_p.cc.

157{
158 return "Smart";
159}

◆ merge()

void SmartMergeStrategy::merge ( Store * dst,
QList< const Store * > srcs,
QList< double > scores ) const
overridevirtual

Call this function to merge a list of meta data stores in one.

Parameters
dstthe destination store
srcsthe list of source meta data store
scoresa list of score which defines the importance of each store compared to the other the sum of score is expected to be equal to 1.0. One way to attribute a score is to compute the area of each layer and then to give a higher score to the biggest layer. srcs and scores list must have the same size.

Implements KisMetaData::MergeStrategy.

Definition at line 237 of file kis_meta_data_merge_strategy_p.cc.

238{
239 dbgMetaData << "Smart merging of meta data";
240 Q_ASSERT(srcs.size() == scores.size());
241 Q_ASSERT(srcs.size() > 0);
242 if (srcs.size() == 1) {
243 dst->copyFrom(srcs[0]);
244 return;
245 }
246 // Initialize some schema
248// const KisMetaData::Schema* psSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::PhotoshopSchemaUri);
251 // Sort the stores and scores
252 {
253 QMultiMap<double, const Store*> scores2srcs;
254 for (int i = 0; i < scores.size(); ++i) {
255 scores2srcs.insert(scores[i], srcs[i]);
256 }
257 srcs = scores2srcs.values();
258 scores = scores2srcs.keys();
259 }
260
261 // First attempt to see if one of the store has a higher score than the others
262 if (scores[0] > 2 * scores[1]) { // One of the store has a higher importance than the other ones
263 dst->copyFrom(srcs[0]);
264 } else {
265 // Merge exif info
266
267
268 // Election
269 Q_FOREACH (const Store* store, srcs) {
270 QList<QString> keys = store->keys();
271 Q_FOREACH (const QString & key, keys) {
272 if (!dst->containsEntry(key)) {
273 Value v = election(srcs, scores, key);
274 if (v.type() != Value::Invalid) {
275 dst->getEntry(key).value() = v;
276 }
277 }
278 }
279 }
280
281 // Compute rating
282 double rating = 0.0;
283 double norm = 0.0;
284 for (int i = 0; i < srcs.size(); i++) {
285 const Store* store = srcs[i];
286 if (store->containsEntry(XMPSchema, "Rating")) {
287 double score = scores[i];
288 rating += score * store->getEntry(XMPSchema, "Rating").value().asVariant().toDouble();
289 norm += score;
290 }
291 }
292 if (norm > 0.01) {
293 dst->getEntry(XMPSchema, "Rating").value() = QVariant((int)(rating / norm));
294 }
295 }
296 // Merge the list of authors and keywords and other stuff
297 mergeEntry(dst, srcs, dcSchema, "contributor");
298 mergeEntry(dst, srcs, dcSchema, "creator");
299 mergeEntry(dst, srcs, dcSchema, "publisher");
300 mergeEntry(dst, srcs, dcSchema, "subject");
301 mergeEntry(dst, srcs, XMPRightsSchema, "Owner");
302 mergeEntry(dst, srcs, XMPSchema, "Identifier");
303}
qreal v
static KisMetaData::SchemaRegistry * instance()
const Schema * schemaFromUri(const QString &uri) const
static const QString XMPRightsSchemaUri
static const QString DublinCoreSchemaUri
static const QString XMPSchemaUri
Value election(QList< const Store * > srcs, QList< double > score, const QString &key) const
void mergeEntry(Store *dst, QList< const Store * > srcs, const Schema *schema, const QString &identifier) const
#define dbgMetaData
Definition kis_debug.h:61
qreal norm(const T &a)

References KisMetaData::Value::asVariant(), KisMetaData::Store::containsEntry(), KisMetaData::Store::copyFrom(), dbgMetaData, KisMetaData::Schema::DublinCoreSchemaUri, election(), KisMetaData::Store::getEntry(), KisMetaData::SchemaRegistry::instance(), KisMetaData::Value::Invalid, KisMetaData::Store::keys(), mergeEntry(), KisMetaData::SchemaRegistry::schemaFromUri(), v, KisMetaData::Entry::value(), KisMetaData::Schema::XMPRightsSchemaUri, and KisMetaData::Schema::XMPSchemaUri.

◆ mergeEntry()

void SmartMergeStrategy::mergeEntry ( Store * dst,
QList< const Store * > srcs,
const Schema * schema,
const QString & identifier ) const
protected

Merge multiple entries in one.

Definition at line 222 of file kis_meta_data_merge_strategy_p.cc.

223{
224 bool foundOnce = false;
226 Q_FOREACH (const Store* store, srcs) {
227 if (store->containsEntry(schema, identifier)) {
228 v += store->getEntry(schema, identifier).value();
229 foundOnce = true;
230 }
231 }
232 if (foundOnce) {
233 dst->getEntry(schema, identifier).value() = v;
234 }
235}

References KisMetaData::Store::containsEntry(), KisMetaData::Store::getEntry(), KisMetaData::Value::OrderedArray, v, and KisMetaData::Entry::value().

◆ name()

QString SmartMergeStrategy::name ( ) const
overridevirtual
Returns
the name of this merge strategy

Implements KisMetaData::MergeStrategy.

Definition at line 160 of file kis_meta_data_merge_strategy_p.cc.

161{
162 return i18n("Smart");
163}

The documentation for this class was generated from the following files: