Esempio n. 1
0
void TagComparator::_addNonConflictingTags(Tags& t1, const Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  // we're deleting as we iterate so be careful making changes.
  for (Tags::iterator it1 = t1.begin(); it1 != t1.end(); )
  {
    QString kvp1 = it1.key() + "=" + it1.value();
    bool conflict = false;
    for (Tags::const_iterator it2 = t2.begin(); it2 != t2.end(); ++it2)
    {
      QString kvp2 = it2.key() + "=" + it2.value();
      if (schema.score(kvp1, kvp2) > 0.0)
      {
        conflict = true;
        break;
      }
    }

    if (conflict)
    {
      ++it1;
    }
    else
    {
      result[it1.key()] = it1.value();
      t1.erase(it1++);
    }
  }
}
Esempio n. 2
0
void TagComparator::_promoteToCommonAncestor(Tags& t1, Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  // we're deleting as we iterate so be careful making changes.
  for (Tags::iterator it1 = t1.begin(); it1 != t1.end(); )
  {
    for (Tags::iterator it2 = t2.begin(); it2 != t2.end(); )
    {
      const SchemaVertex& ancestor = schema.getFirstCommonAncestor(it1.key() + "=" + it1.value(),
        it2.key() + "=" + it2.value());
      if (ancestor.isEmpty() == false)
      {
        // erase from the iterators in a safe way
        t1.erase(it1++);
        t2.erase(it2++);
        if (ancestor.value.isEmpty() == false)
        {
          result[ancestor.key] = ancestor.value;
        }
      }
      else
      {
        // if we didn't erase anything then increment the iterators.
        ++it2;
      }
    }
    if (it1 != t1.end())
    {
      ++it1;
    }
  }
}
Esempio n. 3
0
void TagComparator::_overwriteUnrecognizedTags(Tags& t1, Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  const Tags t1Copy = t1;
  for (Tags::ConstIterator it1 = t1Copy.begin(); it1 != t1Copy.end(); ++it1)
  {
    // if this is an unknown type
    if (schema.getTagVertex(it1.key() + "=" + it1.value()).isEmpty() &&
        schema.getTagVertex(it1.key()).isEmpty())
    {
      // if this is also in t2.
      if (t2.contains(it1.key()))
      {
        result[it1.key()] = it1.value();
        t1.remove(it1.key());
        t2.remove(it1.key());
      }
    }
  }

  // go through any remaining tags in t2
  const Tags t2Copy = t2;
  for (Tags::ConstIterator it2 = t2Copy.begin(); it2 != t2Copy.end(); ++it2)
  {
    // if this is an unknown type
    if (schema.getTagVertex(it2.key() + "=" + it2.value()).isEmpty())
    {
      // we know it isn't in t1, or it would have been handled in the above loop so just deal with
      // t2
      t2.remove(it2.key());
      result[it2.key()] = it2.value();
    }
  }
}
Esempio n. 4
0
void TagComparator::_mergeText(Tags& t1, Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  const Tags t1Copy = t1;
  for (Tags::ConstIterator it1 = t1Copy.begin(); it1 != t1Copy.end(); ++it1)
  {
    const SchemaVertex& tv = schema.getTagVertex(it1.key());

    // if this is a text field and it exists in both tag sets.
    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()));

      // append all unique values in the existing order.
      for (int i = 0; i < values.size(); i++)
      {
        if (values[i].isEmpty() == false)
        {
          result.appendValueIfUnique(it1.key(), values[i]);
        }
      }

      t1.remove(it1.key());
      t2.remove(it1.key());
    }
  }
}
Esempio n. 5
0
//------------------------------------------------------------------------------------------------------------------------------------
// Helper for ErrorMessenger.
//------------------------------------------------------------------------------------------------------------------------------------
LogMgr::ErrorDialogResult LogMgr::Error(const std::string& errorMessage, bool isFatal, const char* funcName, const char* sourceFile, unsigned int lineNum)
{
	string tag = ((isFatal) ? ("FATAL") : ("ERROR"));

	// buffer for our final output string
	string buffer;
	GetOutputBuffer(buffer, tag, errorMessage, funcName, sourceFile, lineNum);

	// write the final buffer to all the various logs
	m_tagCriticalSection.Lock();
	Tags::iterator findIt = m_tags.find(tag);
	if (findIt != m_tags.end())
		OutputFinalBufferToLogs(buffer, findIt->second);
	m_tagCriticalSection.Unlock();

    // show the dialog box
    int result = ::MessageBoxA(NULL, buffer.c_str(), tag.c_str(), MB_ABORTRETRYIGNORE|MB_ICONERROR|MB_DEFBUTTON3);

	// act upon the choice
	switch (result)
	{
		case IDIGNORE : return LogMgr::LOGMGR_ERROR_IGNORE;
		case IDABORT  : __debugbreak(); return LogMgr::LOGMGR_ERROR_RETRY;  // assembly language instruction to break into the debugger
		case IDRETRY :	return LogMgr::LOGMGR_ERROR_RETRY;
		default :       return LogMgr::LOGMGR_ERROR_RETRY;
	}
}
Esempio n. 6
0
void TagComparator::_mergeUnrecognizedTags(Tags& t1, Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  const Tags t1Copy = t1;
  for (Tags::ConstIterator it1 = t1Copy.begin(); it1 != t1Copy.end(); ++it1)
  {
    // if this is an unknown type
    if (schema.getTagVertex(it1.key() + "=" + it1.value()).isEmpty() &&
        schema.getTagVertex(it1.key()).isEmpty())
    {
      // if this is also in t2.
      if (t2.contains(it1.key()))
      {
        // get the set of all values.
        QSet<QString> values = _toSet(t1, it1.key());
        values.unite(_toSet(t2, it1.key()));
        QList<QString> sortEm = values.toList();
        qSort(sortEm);

        // remove it from the inputs
        t1.remove(it1.key());
        t2.remove(it1.key());
        // set the united set in the output
        result.set(it1.key(), sortEm.begin(), sortEm.end());
      }
      else
      {
        result[it1.key()] = it1.value();
      }
    }
  }

  // go through any remaining tags in t2
  const Tags t2Copy = t2;
  for (Tags::ConstIterator it2 = t2Copy.begin(); it2 != t2Copy.end(); ++it2)
  {
    // if this is an unknown type
    if (schema.getTagVertex(it2.key() + "=" + it2.value()).isEmpty())
    {
      // we know it isn't in t1, or it would have been handled in the above loop so just deal with
      // t2
      t2.remove(it2.key());
      result[it2.key()] = it2.value();
    }
  }
}
Esempio n. 7
0
bool TagComparator::nonNameTagsExactlyMatch(const Tags& t1, const Tags& t2)
{
  const Qt::CaseSensitivity caseSensitivity =
    _caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;

  Tags t1Filtered;
  for (Tags::const_iterator it1 = t1.begin(); it1 != t1.end(); it1++)
  {
    QString key = it1.key();
    QString value = it1.value();
    if (!Tags::getNameKeys().contains(key, caseSensitivity) &&
        //Metadata keys are controlled by hoot and, therefore, should always be lower case, so no
        //case check needed.
        !OsmSchema::getInstance().isMetaData(key, value))
    {
      if (!_caseSensitive)
      {
        key = key.toUpper();
        value = value.toUpper();
      }
      t1Filtered.insert(key, value);
    }
  }

  Tags t2Filtered;
  for (Tags::const_iterator it2 = t2.begin(); it2 != t2.end(); it2++)
  {
    QString key = it2.key();
    QString value = it2.value();
    if (!Tags::getNameKeys().contains(key, caseSensitivity) &&
        !OsmSchema::getInstance().isMetaData(key, value))
    {
      if (!_caseSensitive)
      {
        key = key.toUpper();
        value = value.toUpper();
      }
      t2Filtered.insert(key, value);
    }
  }

  return t1Filtered == t2Filtered;
}
Esempio n. 8
0
void LogManager::Log(const std::string& tag, const std::string& msg, const char* funcName, const char* fileName, unsigned int lineNum) 
{
	m_CritSection.Lock();
	Tags::iterator findIt = m_Tags.find(tag);
	if (findIt != m_Tags.end())
	{
		std::string buffer;
		GetOutputBuffer(buffer, tag, msg, funcName, fileName, lineNum);
		OutputBufferToLogs(buffer, findIt->second);
	}
	m_CritSection.Unlock();
}
/* topological (depth-first) sorting of operations */
static void sort_operations_recursive(NodeOperationBuilder::Operations &sorted, Tags &visited, NodeOperation *op)
{
	if (visited.find(op) != visited.end())
		return;
	visited.insert(op);
	
	for (int i = 0; i < op->getNumberOfInputSockets(); ++i) {
		NodeOperationInput *input = op->getInputSocket(i);
		if (input->isConnected())
			sort_operations_recursive(sorted, visited, &input->getLink()->getOperation());
	}
	
	sorted.push_back(op);
}
Esempio n. 10
0
void LogManager::SetDisplayFlags(const std::string& tag, unsigned char flag)
{
	m_CritSection.Lock();
	if (flag != 0)
	{
		Tags::iterator findIt = m_Tags.find(tag);
		if (findIt == m_Tags.end())
			m_Tags.insert(std::make_pair(tag, flag));
		else
			findIt->second = flag;
	}
	else
		m_Tags.erase(tag);
	m_CritSection.Unlock();
}
static void add_group_operations_recursive(Tags &visited, NodeOperation *op, ExecutionGroup *group)
{
	if (visited.find(op) != visited.end())
		return;
	visited.insert(op);
	
	if (!group->addOperation(op))
		return;
	
	/* add all eligible input ops to the group */
	for (int i = 0; i < op->getNumberOfInputSockets(); ++i) {
		NodeOperationInput *input = op->getInputSocket(i);
		if (input->isConnected())
			add_group_operations_recursive(visited, &input->getLink()->getOperation(), group);
	}
}
Esempio n. 12
0
///////////////////////////////////////////////////////////////////////////////////////
// sets one or more display flags
///////////////////////////////////////////////////////////////////////////////////////
void LogMgr::SetDisplayFlags(const std::string& tag, unsigned char flags)
{
  _tag_critical_section.Lock();
  if(flags != 0)
  {
    Tags::iterator it = _tags.find(tag);
    if(it == _tags.end())
      _tags.insert(std::make_pair(tag, flags));
    else
      it->second = flags;
  }
  else
  {
    _tags.erase(tag);
  }
  _tag_critical_section.Unlock();
}
Esempio n. 13
0
///////////////////////////////////////////////////////////////////////////////////////////////////////
// this function builds up the log string and outputs it to various places based on display flags
///////////////////////////////////////////////////////////////////////////////////////////////////////
void LogMgr::Log(const string& tag, const string& message, const char* func, const char* source, unsigned int line)
{
  _tag_critical_section.Lock();
  Tags::iterator it = _tags.find(tag);
  if(it != _tags.end())
  {
    _tag_critical_section.Unlock();
    string buffer;
    GetOutputBuffer(buffer, tag, message, func, source, line);
    OutputFinalBufferToLogs(buffer, it->second);
  }
  else
  {
    //critical section is exited in the if above, so need to do it here if above wasnt executed
    _tag_critical_section.Unlock();
  }
}
Esempio n. 14
0
	void LogMgr::setDisplayFLags(const std::string& tag, unsigned char flags)
	{
		m_TagCriticalSection.lock();
		if (flags != 0)
		{
			Tags::iterator findIt = m_Tags.find(tag);
			if (findIt == m_Tags.end())
				m_Tags.insert(std::make_pair(tag, flags));
			else
				findIt->second = flags;
		}
		else
		{
			m_Tags.erase(tag);
		}
		m_TagCriticalSection.unlock();
	}
Esempio n. 15
0
	void LogMgr::log(const std::string& tag, const std::string& message, const char* funcName, const char* sourceFile, unsigned int lineNum)
	{
		m_TagCriticalSection.lock();
		Tags::iterator findIt = m_Tags.find(tag);
		if (findIt != m_Tags.end())
		{
			m_TagCriticalSection.unlock();

			std::string buffer;
			getOutputBuffer(buffer, tag, message, funcName, sourceFile, lineNum);
			outputFinalBufferToLogs(buffer, tag, findIt->second);
		}
		else
		{
			m_TagCriticalSection.unlock();
		}
	}
Esempio n. 16
0
void OsmApiDbSqlChangesetFileWriter::_createTags(ConstElementPtr element)
{
  LOG_TRACE("Creating tags for: " << element->getElementId());

  QStringList tableNames = _tagTableNamesForElement(element->getElementId());

  Tags tags = element->getTags();
  if (_includeDebugTags)
  {
    tags.set(MetadataTags::HootStatus(), QString::number(element->getStatus().getEnum()));
  }
  LOG_VART(tags);
  if (element->getElementType().getEnum() == ElementType::Relation && !tags.contains("type"))
  {
    ConstRelationPtr tmp = boost::dynamic_pointer_cast<const Relation>(element);
    tags.appendValue("type", tmp->getType());
  }

  for (Tags::const_iterator it = tags.begin(); it != tags.end(); ++it)
  {
    QString k = it.key();
    QString v = it.value();

    if (k != MetadataTags::HootHash())
    {
      const QString currentTagValues =
      QString("(%1_id, k, v) VALUES (%2, '%3', '%4');\n")
        .arg(element->getElementId().getType().toString().toLower())
        .arg(element->getElementId().getId())
        .arg(k.replace('\'', "''"))
        .arg(v.replace('\'', "''"));

      const QString tagValues =
        QString("(%1_id, k, v, version) VALUES (%2, '%3', '%4', %5);\n")
          .arg(element->getElementId().getType().toString().toLower())
          .arg(element->getElementId().getId())
          .arg(k.replace('\'', "''"))
          .arg(v.replace('\'', "''"))
          .arg(element->getVersion());

      _outputSql.write(
        (QString("INSERT INTO %1 ").arg(tableNames.at(0)) + currentTagValues).toUtf8());
      _outputSql.write((QString("INSERT INTO %1 ").arg(tableNames.at(1)) + tagValues).toUtf8());
    }
  }
}
Esempio n. 17
0
QString ServicesDb::_escapeTags(const Tags& tags) const
{
  QStringList l;
  static QChar f1('\\'), f2('"'), f3('\'');
  static QChar to('_');

  for (Tags::const_iterator it = tags.begin(); it != tags.end(); ++it)
  {
    // this doesn't appear to be working, but I think it is implementing the spec as described here:
    // http://www.postgresql.org/docs/9.0/static/hstore.html
    // The spec described above does seem to work on the psql command line. Curious.
    QString k = QString(it.key()).replace(f1, "\\\\").replace(f2, "\\\"");
    QString v = QString(it.value()).replace(f1, "\\\\").replace(f2, "\\\"");

    l << QString("\"%1\"=>\"%2\"").arg(k).arg(v);
  }
  return l.join(",");
}
Esempio n. 18
0
//------------------------------------------------------------------------------------------------------------------------------------
// This function builds up the log string and outputs it to various places based on the display flags (m_displayFlags).
//------------------------------------------------------------------------------------------------------------------------------------
void LogMgr::Log(const string& tag, const string& message, const char* funcName, const char* sourceFile, unsigned int lineNum)
{
	m_tagCriticalSection.Lock();
	Tags::iterator findIt = m_tags.find(tag);
	if (findIt != m_tags.end())
	{
		m_tagCriticalSection.Unlock();
		
		string buffer;
		GetOutputBuffer(buffer, tag, message, funcName, sourceFile, lineNum);
		OutputFinalBufferToLogs(buffer, findIt->second);
	}
	else
	{
		// Critical section is exited in the if statement above, so we need to exit it here if that didn't 
		// get executed.
        m_tagCriticalSection.Unlock();
	}
}  // end LogMgr::Log()
Esempio n. 19
0
  void compareTags(const Tags& t1, const Tags& t2)
  {
    if (t1.size() != t2.size())
    {
      LOG_WARN("t1: " << t1.toString());
      LOG_WARN("t2: " << t2.toString());
      CPPUNIT_ASSERT_EQUAL(t1.size(), t2.size());
    }

    for (Tags::const_iterator it = t1.begin(); it != t1.end(); it++)
    {
      if (t1[it.key()] != t2[it.key()])
      {
        LOG_WARN("t1: " << t1.toString());
        LOG_WARN("t2: " << t2.toString());
        CPPUNIT_ASSERT_EQUAL(t1[it.key()].toStdString(), t2[it.key()].toStdString());
      }
    }
  }
static void find_reachable_operations_recursive(Tags &reachable, NodeOperation *op)
{
	if (reachable.find(op) != reachable.end())
		return;
	reachable.insert(op);
	
	for (int i = 0; i < op->getNumberOfInputSockets(); ++i) {
		NodeOperationInput *input = op->getInputSocket(i);
		if (input->isConnected())
			find_reachable_operations_recursive(reachable, &input->getLink()->getOperation());
	}
	
	/* associated write-buffer operations are executed as well */
	if (op->isReadBufferOperation()) {
		ReadBufferOperation *read_op = (ReadBufferOperation *)op;
		MemoryProxy *memproxy = read_op->getMemoryProxy();
		find_reachable_operations_recursive(reachable, memproxy->getWriteBufferOperation());
	}
}
Esempio n. 21
0
void SplitNameVisitor::visit(const shared_ptr<Element>& e)
{
    Tags& t = e->getTags();

    QStringList extraNames;

    Tags copy = t;
    for (Tags::const_iterator it = copy.begin(); it != copy.end(); ++it)
    {
        const QString& k = it.key();
        const QString& v = it.value();
        if (v.size() > _maxSize &&
                OsmSchema::getInstance().getCategories(it.key()).intersects(OsmSchemaCategory::name()))
        {
            QStringList l = _splitNames(v, extraNames);
            t.setList(k, l);
        }
    }

    _addExtraNames(t, extraNames);
}
Esempio n. 22
0
	LogMgr::ErrorDialogResult LogMgr::error(const std::string & errorMessage, bool isFatal, const char* funcName, const char* sourceFile, unsigned int lineNum)
	{
		std::string tag = ((isFatal) ? ("FATAL") : ("ERROR"));

		std::string buffer;
		getOutputBuffer(buffer, tag, errorMessage, funcName, sourceFile, lineNum);

		m_TagCriticalSection.lock();
		Tags::iterator findIt = m_Tags.find(tag);
		if (findIt != m_Tags.end())
			outputFinalBufferToLogs(buffer, tag, findIt->second);
		m_TagCriticalSection.unlock();

		int result = ::MessageBoxA(NULL, buffer.c_str(), tag.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR | MB_DEFBUTTON3);

		switch (result)
		{
		case IDIGNORE: return LogMgr::LOGMGR_ERROR_IGNORE;
		case IDABORT: __debugbreak();  return LogMgr::LOGMGR_ERROR_RETRY;
		case IDRETRY: return LogMgr::LOGMGR_ERROR_RETRY;
		default: return LogMgr::LOGMGR_ERROR_RETRY;
		}
	}
Esempio n. 23
0
void TagComparator::compareTextTags(const Tags& t1, const Tags& t2, double& score, double& weight)
{
  OsmSchema& schema = OsmSchema::getInstance();

  score = 1.0;
  weight = 0.0;

  for (Tags::const_iterator it = t1.begin(); it != t1.end(); it++)
  {
    const SchemaVertex& tv = schema.getTagVertex(it.key());
    if (schema.isAncestor(it.key(), "abstract_name") == false &&
        tv.valueType == Text && t2.contains(it.key()))
    {
      score *= LevenshteinDistance::score(it.value(), t2[it.key()]);
      weight += tv.influence;
    }
  }

  // if the weight is zero don't confuse things with a low score.
  if (weight == 0.0)
  {
    score = 1;
  }
}
Esempio n. 24
0
//////////////////////////////////////////////////////////////////////////////////////////////
//helper for ErrorMessenger
/////////////////////////////////////////////////////////////////////////////////////////////
LogMgr::ErrorDialogResult LogMgr::Error(const std::string& error_message, bool is_fatal, const char* func, const char* source, unsigned int line)
{
  string tag = ((is_fatal) ? ("FATAL") : ("ERROR"));
  //buffer for final output string
  string buffer;
  GetOutputBuffer(buffer, tag, error_message, func, source, line);

  //write final buffer to various logs
  _tag_critical_section.Lock();
  Tags::iterator it = _tags.find(tag);
  if(it != _tags.end())
    OutputFinalBufferToLogs(buffer, it->second);
  _tag_critical_section.Unlock();

  //show the dialog box
  int result = ::MessageBoxA(NULL, buffer.c_str(), tag.c_str(),  MB_ABORTRETRYIGNORE|MB_ICONERROR|MB_DEFBUTTON3);
  switch(result)
  {
    case IDIGNORE:  return LogMgr::LOGMGR_ERROR_IGNORE;
    case IDABORT: __debugbreak(); return LogMgr::LOGMGR_ERROR_ABORT;
    case IDRETRY: return LogMgr::LOGMGR_ERROR_RETRY;
    default:  return LogMgr::LOGMGR_ERROR_RETRY;
  }
}
Esempio n. 25
0
LogManager::ErrorDialogResult LogManager::Error(const std::string& msg, bool isFatal, const char* funcName, const char* fileName, unsigned int lineNum)
{
	std::string tag = ((isFatal) ? "FATAL" : "ERROR");
	std::string buffer;

	GetOutputBuffer(buffer, tag, msg, funcName, fileName, lineNum);
	
	m_CritSection.Lock();
	Tags::iterator findIt = m_Tags.find(tag);
	if (findIt != m_Tags.end())
		OutputBufferToLogs(buffer, findIt->second);
	m_CritSection.Unlock();
	
	int result;
	
	// show dialog box
	if (isFatal)
		result = MessageBox(nullptr, buffer.c_str(), tag.c_str(), MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
	else
		result = MessageBox(nullptr, buffer.c_str(), tag.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR | MB_DEFBUTTON3);

	switch (result)
	{
		case IDOK:
			exit(EXIT_FAILURE);
		case IDIGNORE:
			return LogManager::ERROR_DIALOG_IGNORE;
		case IDABORT:
			__debugbreak(); // Assembly instruction to open VS debugger.
			return LogManager::ERROR_DIALOG_ABORT;
		case IDRETRY:
			return LogManager::ERROR_DIALOG_RETRY;
		default:
			return LogManager::ERROR_DIALOG_RETRY;
	}
}
void NodeOperationBuilder::prune_operations()
{
	Tags reachable;
	for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
		NodeOperation *op = *it;
		
		/* output operations are primary executed operations */
		if (op->isOutputOperation(m_context->isRendering()))
			find_reachable_operations_recursive(reachable, op);
	}
	
	/* delete unreachable operations */
	Operations reachable_ops;
	for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
		NodeOperation *op = *it;
		
		if (reachable.find(op) != reachable.end())
			reachable_ops.push_back(op);
		else
			delete op;
	}
	/* finally replace the operations list with the pruned list */
	m_operations = reachable_ops;
}
Esempio n. 27
0
void TagComparator::_mergeExactMatches(Tags& t1, Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  Tags t1Copy = t1;
  for (Tags::ConstIterator it1 = t1Copy.begin(); it1 != t1Copy.end(); ++it1)
  {
    bool keepIt = false;
    Tags::const_iterator it2 = t2.find(it1.key());
    if (it2 != t2.end())
    {
      if (schema.isList(it1.key(), it1.value()))
      {
        // treat the inputs as unordered lists
        QSet<QString> values1 = QSet<QString>::fromList(t1.getList(it1.key()));
        QSet<QString> values2 = QSet<QString>::fromList(t2.getList(it2.key()));
        values1.intersect(values2);
        if (values1.size() == values2.size())
        {
          keepIt = true;
        }
      }
      else if (it2.value() == it1.value())
      {
        keepIt = true;
      }

      if (keepIt)
      {
        result[it1.key()] = it1.value();
        t1.remove(it1.key());
        t2.remove(it1.key());
      }
    }
  }
}
Esempio n. 28
0
shared_ptr<Relation> BuildingPartMergeOp::combineParts(const OsmMapPtr& map,
  const vector< shared_ptr<Element> >& parts)
{
  assert(parts.size() > 0);
  shared_ptr<Relation> building(new Relation(parts[0]->getStatus(),
    map->createNextRelationId(), -1, "building"));

  OsmSchema& schema = OsmSchema::getInstance();
  Tags& t = building->getTags();

  for (size_t i = 0; i < parts.size(); i++)
  {
    building->addElement("part", parts[i]);

    Tags pt = parts[i]->getTags();

    Tags tCopy = t;
    Tags names;
    TagComparator::getInstance().mergeNames(tCopy, pt, names);
    t.set(names);

    // go through all the tags.
    for (Tags::const_iterator it = pt.begin(); it != pt.end(); it++)
    {
      // ignore all keys that are building:part specific.
      if (_buildingPartTagNames.find(it.key()) == _buildingPartTagNames.end())
      {
        // if the tag isn't already in the relation
        if (t.contains(it.key()) == false)
        {
          t[it.key()] = it.value();
        }
        // if this is an arbitrary text value, then concatenate the values.
        else if (schema.isTextTag(it.key()))
        {
          t.appendValueIfUnique(it.key(), it.value());
        }
        // if the tag is in the relation and the tags differ.
        else if (t[it.key()] != it.value())
        {
          t[it.key()] = "";
        }
      }
    }
  }

  // go through all the keys that were consistent for each of the parts and move them into the
  // relation.
  Tags tCopy = t;
  for (Tags::const_iterator it = tCopy.begin(); it != tCopy.end(); it++)
  {
    // if the value is empty, then the tag isn't needed, or it wasn't consistent between multiple
    // parts.
    if (it.value() == "")
    {
      t.remove(it.key());
    }
    // if the tag isn't empty, remove it from each of the parts.
    else
    {
      for (size_t i = 0; i < parts.size(); i++)
      {
        parts[i]->getTags().remove(it.key());
      }
    }
  }

  if (t.contains("building") == false)
  {
    t["building"] = "yes";
  }

  // replace the building tag with building:part tags.
  for (size_t i = 0; i < parts.size(); i++)
  {
    parts[i]->getTags().remove("building");
    parts[i]->getTags()["building:part"] = "yes";
  }

  map->addRelation(building);
  return building;
}
Esempio n. 29
0
void TagComparator::mergeNames(Tags& t1, Tags& t2, Tags& result)
{
  set<QString> altNames, nonAltNames;
  set<QString> toRemove;

  toRemove.insert("alt_name");

  for (Tags::const_iterator it1 = t1.begin(); it1 != t1.end(); it1++)
  {
    if (it1.key() == "alt_name")
    {
      QStringList sl = Tags::split(it1.value());
      altNames.insert(sl.begin(), sl.end());
    }
    else
    {
      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());
      }
    }
  }

  for (Tags::const_iterator it2 = t2.begin(); it2 != t2.end(); it2++)
  {
    if (it2.key() == "alt_name")
    {
      QStringList sl = Tags::split(it2.value());
      altNames.insert(sl.begin(), sl.end());
    }
    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
    {
      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());
      }
    }
  }

  for (set<QString>::const_iterator it = toRemove.begin(); it != toRemove.end(); it++)
  {
    t1.remove(*it);
    t2.remove(*it);
  }

  // add all the altNames that don't exist in nonAltNames
  QStringList l;
  for (set<QString>::const_iterator it = altNames.begin(); it != altNames.end(); it++)
  {
    if (nonAltNames.find(*it) == nonAltNames.end())
    {
      l.append(*it);
    }
  }

  if (l.size() > 0)
  {
    result.setList("alt_name", l);
  }
}