Skip to content

v0.2.48..v0.2.49 changeset TagComparator.cpp

Garret Voltz edited this page Oct 2, 2019 · 1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/schema/TagComparator.cpp b/hoot-core/src/main/cpp/hoot/core/schema/TagComparator.cpp
index c55a2c3..31019a7 100644
--- a/hoot-core/src/main/cpp/hoot/core/schema/TagComparator.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/schema/TagComparator.cpp
@@ -59,9 +59,11 @@ struct Entry
   }
 };
 
-TagComparator::TagComparator()
+TagComparator::TagComparator() :
+_caseSensitive(false)
 {
-  setCaseSensitive(ConfigOptions().getDuplicateNameCaseSensitive());
+  ConfigOptions opts(conf());
+  setCaseSensitive(opts.getDuplicateNameCaseSensitive());
 }
 
 void TagComparator::_addAsDefault(Tags& t, const QString& key, const QString& value)
@@ -540,33 +542,40 @@ void TagComparator::_mergeExactMatches(Tags& t1, Tags& t2, Tags& result)
   }
 }
 
-void TagComparator::mergeNames(Tags& t1, Tags& t2, Tags& result)
+void TagComparator::mergeNames(Tags& t1, Tags& t2, Tags& result,
+                               const QStringList& overwriteExcludeTagKeys)
 {
+  LOG_DEBUG("Merging names...");
   LOG_VART(t1);
   LOG_VART(t2);
+  LOG_VART(result);
+  LOG_VART(overwriteExcludeTagKeys);
 
   set<QString> altNames, nonAltNames;
   set<QString> toRemove;
+  const Qt::CaseSensitivity caseSensitivity =
+    _caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
+  LOG_VART(_caseSensitive);
 
   toRemove.insert("alt_name");
 
   for (Tags::const_iterator it1 = t1.begin(); it1 != t1.end(); ++it1)
   {
-    if (it1.key() == "alt_name")
+    LOG_VART(it1.key());
+    LOG_VART(it1.value());
+    if (it1.key() == "alt_name" && !overwriteExcludeTagKeys.contains("alt_name"))
     {
       QStringList sl = Tags::split(it1.value());
       altNames.insert(sl.begin(), sl.end());
     }
-    else
+    else if (OsmSchema::getInstance().isAncestor(it1.key(), "abstract_name") &&
+             !overwriteExcludeTagKeys.contains(it1.key(), caseSensitivity))
     {
-      if (OsmSchema::getInstance().isAncestor(it1.key(), "abstract_name"))
-      {
-        result[it1.key()] = it1.value();
-        QStringList sl = Tags::split(it1.value());
-        // keep track of all the names we've used
-        nonAltNames.insert(sl.begin(), sl.end());
-        toRemove.insert(it1.key());
-      }
+      result[it1.key()] = it1.value();
+      QStringList sl = Tags::split(it1.value());
+      // keep track of all the names we've used
+      nonAltNames.insert(sl.begin(), sl.end());
+      toRemove.insert(it1.key());
     }
   }
   LOG_VART(altNames);
@@ -576,6 +585,8 @@ void TagComparator::mergeNames(Tags& t1, Tags& t2, Tags& result)
 
   for (Tags::const_iterator it2 = t2.begin(); it2 != t2.end(); ++it2)
   {
+    LOG_VART(it2.key());
+    LOG_VART(it2.value());
     if (it2.key() == "alt_name")
     {
       QStringList sl = Tags::split(it2.value());
@@ -583,23 +594,18 @@ void TagComparator::mergeNames(Tags& t1, Tags& t2, Tags& result)
     }
     else if (result.contains(it2.key()))
     {
-      const Qt::CaseSensitivity caseSensitivity =
-        _caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
       if (result[it2.key()].compare(it2.value(), caseSensitivity) != 0)
       {
         QStringList sl = Tags::split(it2.value());
         altNames.insert(sl.begin(), sl.end());
       }
     }
-    else
+    else if (OsmSchema::getInstance().isAncestor(it2.key(), "abstract_name"))
     {
-      if (OsmSchema::getInstance().isAncestor(it2.key(), "abstract_name"))
-      {
-        result[it2.key()] = it2.value();
-        QStringList sl = Tags::split(it2.value());
-        nonAltNames.insert(sl.begin(), sl.end());
-        toRemove.insert(it2.key());
-      }
+      result[it2.key()] = it2.value();
+      QStringList sl = Tags::split(it2.value());
+      nonAltNames.insert(sl.begin(), sl.end());
+      toRemove.insert(it2.key());
     }
   }
   LOG_VART(altNames);
@@ -633,8 +639,12 @@ void TagComparator::mergeNames(Tags& t1, Tags& t2, Tags& result)
   LOG_VART(result);
 }
 
-void TagComparator::mergeText(Tags& t1, Tags& t2, Tags& result)
+void TagComparator::mergeText(Tags& t1, Tags& t2, Tags& result,
+                              const QStringList& overwriteExcludeTagKeys)
 {
+  LOG_DEBUG("Merging text...");
+  LOG_VART(t1);
+  LOG_VART(t2);
   OsmSchema& schema = OsmSchema::getInstance();
 
   const Tags t1Copy = t1;
@@ -646,15 +656,33 @@ void TagComparator::mergeText(Tags& t1, Tags& t2, Tags& result)
     if (tv.valueType == Text && t2.contains(it1.key()))
     {
       // only keep the unique text fields
-      QStringList values = t1.getList(it1.key());
-      values.append(t2.getList(it1.key()));
+      QStringList values1 = t1.getList(it1.key());
+      LOG_VART(values1);
+      QStringList values2 = t2.getList(it1.key());
+      LOG_VART(values2);
 
-      // append all unique values in the existing order.
-      for (int i = 0; i < values.size(); i++)
+      // append all unique values in the existing order; don't overwrite tags in t2 that are in the
+      // exclude list
+      const Qt::CaseSensitivity caseSensitivity =
+        _caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
+      for (int i = 0; i < values1.size(); i++)
       {
-        if (values[i].isEmpty() == false)
+        LOG_VART(values1[i]);
+        if (values1[i].isEmpty() == false &&
+            (!t2.contains(it1.key()) ||
+             !overwriteExcludeTagKeys.contains(it1.key(), caseSensitivity)))
         {
-          result.appendValueIfUnique(it1.key(), values[i]);
+          result.appendValueIfUnique(it1.key(), values1[i]);
+          LOG_VART(result);
+        }
+      }
+      for (int i = 0; i < values2.size(); i++)
+      {
+        LOG_VART(values2[i]);
+        if (values2[i].isEmpty() == false)
+        {
+          result.appendValueIfUnique(it1.key(), values2[i]);
+          LOG_VART(result);
         }
       }
 
@@ -662,6 +690,7 @@ void TagComparator::mergeText(Tags& t1, Tags& t2, Tags& result)
       t2.remove(it1.key());
     }
   }
+  LOG_VART(result);
 }
 
 void TagComparator::_mergeUnrecognizedTags(Tags& t1, Tags& t2, Tags& result)
@@ -712,34 +741,29 @@ void TagComparator::_mergeUnrecognizedTags(Tags& t1, Tags& t2, Tags& result)
   }
 }
 
-Tags TagComparator::overwriteMerge(Tags t1, Tags t2)
-{
+Tags TagComparator::overwriteMerge(Tags t1, Tags t2, const QStringList& overwriteExcludeTagKeys)
+{ 
   Tags result;
 
   // Names are merged using _mergeNames.
-  mergeNames(t1, t2, result);
+  mergeNames(t1, t2, result, overwriteExcludeTagKeys);
 
   // concatenate the known text fields (e.g. note)
-  mergeText(t1, t2, result);
+  mergeText(t1, t2, result, overwriteExcludeTagKeys);
 
   // use the tags in t1 first, then fall back to tags in t2
-  _overwriteRemainingTags(t1, t2, result);
+  _overwriteRemainingTags(t1, t2, result, overwriteExcludeTagKeys);
 
   return result;
 }
 
-Tags TagComparator::overwriteAllMerge(Tags t1, Tags t2)
+void TagComparator::_overwriteRemainingTags(Tags& t1, Tags& t2, Tags& result,
+                                            const QStringList& overwriteExcludeTagKeys)
 {
-  Tags result;
-
-  // use the tags in t1 first, then fall back to tags in t2
-  _overwriteRemainingTags(t1, t2, result);
-
-  return result;
-}
+  LOG_DEBUG("Overwriting remaining tags...");
+  LOG_VART(t1);
+  LOG_VART(t2);
 
-void TagComparator::_overwriteRemainingTags(Tags& t1, Tags& t2, Tags& result)
-{
   // Add t2 tags
   for (Tags::ConstIterator it2 = t2.constBegin(); it2 != t2.constEnd(); ++it2)
   {
@@ -748,15 +772,25 @@ void TagComparator::_overwriteRemainingTags(Tags& t1, Tags& t2, Tags& result)
       result[it2.key()] = it2.value();
     }
   }
+  LOG_VART(result);
 
-  // Add t1 tags overwriting any t2 tags in the process.
+  // Add t1 tags overwriting any t2 tags in the process (except those in the optional exclude list).
+  const Qt::CaseSensitivity caseSensitivity =
+    _caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
   for (Tags::ConstIterator it1 = t1.constBegin(); it1 != t1.constEnd(); ++it1)
   {
-    if (it1.value().isEmpty() == false)
+    LOG_VART(it1.key());
+    LOG_VART(it1.value());
+    LOG_VART(overwriteExcludeTagKeys.contains(it1.key(), caseSensitivity));
+    LOG_VART(result.contains(it1.key()));
+    if (it1.value().isEmpty() == false &&
+        (!result.contains(it1.key()) ||
+         !overwriteExcludeTagKeys.contains(it1.key(), caseSensitivity)))
     {
       result[it1.key()] = it1.value();
     }
   }
+  LOG_VART(result);
 
   t1.clear();
   t2.clear();
Clone this wiki locally