Example #1
0
    /// get dof-nrs of domain or boundary element elnr
    void GetDofNrs (ElementId ei, Array<int> & dnums) const
    {
      if (ei.IsBoundary())
	GetSDofNrs (ei.Nr(), dnums);
      else
	GetDofNrs (ei.Nr(), dnums);
    }
Example #2
0
  void HDivDivSurfaceSpace::GetDofNrs(ElementId ei, Array<int> & dnums) const
  {
    dnums.SetSize0();
    
    switch (ei.VB())
      {
      case VOL:
        break;

      case BND:
        {
          for (auto e : ma->GetElEdges(ei))
            dnums += Range (first_face_dof[e], first_face_dof[e+1]);
          dnums += Range (first_element_dof[ei.Nr()], first_element_dof[ei.Nr()+1]);
          break;
        }
          
      case BBND:
        {
          GetEdgeDofNrs(ma->GetElEdges(ei)[0], dnums);
          break;
        }

      case BBBND:
        break;
      }
  }
ConstElementPtr ElementCacheLRU::getElement(const ElementId& eid) const
{
  const long id = eid.getId();
  ConstElementPtr returnPtr;
  switch ( eid.getType().getEnum() )
  {
  case ElementType::Node:
    returnPtr = getNode(id);
    break;

  case ElementType::Way:
    returnPtr = _ways.find(id)->second.first;

    break;

  case ElementType::Relation:
    returnPtr = _relations.find(id)->second.first;

    break;

  // Intentional fallthrow
  case ElementType::Unknown:
  default:

    break;
  }

  return returnPtr;
}
Example #4
0
QStringList OsmApiDbSqlChangesetFileWriter::_tagTableNamesForElement(const ElementId& eid) const
{
  QStringList tableNames;
  const QString tableName1 = "current_" + eid.getType().toString().toLower() + "_tags";
  tableNames.append(tableName1);
  const QString tableName2 = eid.getType().toString().toLower() + "_tags";
  tableNames.append(tableName2);
  return tableNames;
}
Example #5
0
ElementId OsmApiDbReader::_mapElementId(const OsmMap& map, ElementId oldId)
{
  ElementId result;
  if (_useDataSourceIds)
  {
    result = oldId;
  }
  else
  {
    long id = oldId.getId();
    switch (oldId.getType().getEnum())
    {
    case ElementType::Node:
      if (_nodeIdMap.count(id) > 0)
      {
        result = ElementId::node(_nodeIdMap.at(id));
      }
      else
      {
        long newId = map.createNextNodeId();
        _nodeIdMap[id] = newId;
        result = ElementId::node(newId);
      }
      break;
    case ElementType::Way:
      if (_wayIdMap.count(id) > 0)
      {
        result = ElementId::way(_wayIdMap.at(id));
      }
      else
      {
        long newId = map.createNextWayId();
        _wayIdMap[id] = newId;
        result = ElementId::way(newId);
      }
      break;
    case ElementType::Relation:
      if (_relationIdMap.count(id) > 0)
      {
        result = ElementId::relation(_relationIdMap.at(id));
      }
      else
      {
        long newId = map.createNextRelationId();
        _relationIdMap[id] = newId;
        result = ElementId::relation(newId);
      }
      break;
    default:
      throw IllegalArgumentException("Expected a valid element type, but got: " +
        QString::number(oldId.getType().getEnum()));
    }
  }

  return result;
}
  void runEmptyRelationNoMemberCountTagTest()
  {
    //add some nodes to a map
    OsmMapPtr map(new OsmMap());
    ElementPtr n1(new Node(Status::Unknown1, 1, 0, 0, 0));
    ElementPtr n2(new Node(Status::Unknown2, 2, 0, 0, 0));
    ElementPtr n3(new Node(Status::Unknown1, 3, 0, 0, 0));
    ElementPtr n4(new Node(Status::Unknown2, 4, 0, 0, 0));
    map->addElement(n1);
    map->addElement(n2);
    map->addElement(n3);
    map->addElement(n4);

    //create two reviews involving the two pairs of nodes
    ReviewMarker reviewMarker;
    reviewMarker.mark(map, n1, n2, "note 1", "test 1");
    reviewMarker.mark(map, n3, n4, "note 2", "test 2");
    CPPUNIT_ASSERT_EQUAL((size_t)2, map->getRelations().size());
    CPPUNIT_ASSERT(reviewMarker.isNeedsReview(map, n1, n2));
    CPPUNIT_ASSERT(reviewMarker.isNeedsReview(map, n3, n4));

    //get the review relations
    set<ElementId> review1 = reviewMarker._getReviewRelations(map, n1->getElementId());
    CPPUNIT_ASSERT_EQUAL((size_t)1, review1.size());
    const ElementId r1Id = *review1.begin()++;
    set<ElementId> review2 = reviewMarker._getReviewRelations(map, n3->getElementId());
    CPPUNIT_ASSERT_EQUAL((size_t)1, review2.size());
    const ElementId r2Id = *review2.begin()++;
    RelationPtr relation1 = map->getRelation(r1Id.getId());
    RelationPtr relation2 = map->getRelation(r2Id.getId());

    //go ahead and remove their review member count tags
    relation1->getTags().remove(MetadataTags::HootReviewMembers());
    relation2->getTags().remove(MetadataTags::HootReviewMembers());

    //remove all of one of the review relation's members
    RemoveElementOp::removeElement(map, n3->getElementId());
    RemoveElementOp::removeElement(map, n4->getElementId());
    relation2->removeElement(n3->getElementId());
    relation2->removeElement(n4->getElementId());

    //run the visitor
    RemoveInvalidReviewRelationsVisitor v;
    map->visitRw(v);

    //the empty review relation should have been removed
    CPPUNIT_ASSERT_EQUAL((size_t)1, map->getRelations().size());
    CPPUNIT_ASSERT(map->containsElement(r1Id));
    CPPUNIT_ASSERT(!map->containsElement(r2Id));
  }
void DecomposeBuildingRelationsVisitor::_decomposeBuilding(const shared_ptr<Relation>& r)
{
  Tags baseTags = r->getTags();

  const vector<RelationData::Entry> members = r->getMembers();

  for (size_t i = 0; i < members.size(); ++i)
  {
    ElementId eid = members[i].getElementId();
    r->removeElement(eid);
    if (eid.getType() == ElementType::Node)
    {
      LOG_WARN("Unexpected node encountered in building relation. " << r->getElementId());
      continue;
    }
    // we're dropping the outline. We only care about the parts.
    else if (members[i].getRole() == "outline")
    {
      continue;
    }
    else if (members[i].getRole() != "part")
    {
      LOG_WARN("Encountered an unexpected role in a building relation. " << r->getElementId());
    }

    // ok, we've got a building part. Recompose it as a building.
    shared_ptr<Element> e = _map->getElement(members[i].getElementId());

    Tags t = baseTags;
    t.addTags(e->getTags());
    // don't need the building:part tag anymore.
    t.remove("building:part");

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

    e->setTags(t);
  }

  // remove the building relation
  RecursiveElementRemover(r->getElementId()).apply(_map->shared_from_this());
}
Example #8
0
void OsmApiDbSqlChangesetFileWriter::_deleteCurrentTags(const ElementId& eid)
{
  LOG_TRACE("Deleting tags for: " << eid);
  QStringList tableNames = _tagTableNamesForElement(eid);
  foreach (QString tableName, tableNames)
  {
    QString idFieldName = tableName;
    idFieldName.replace("current_", "").replace("_tags", "");
    idFieldName += "_id";
    _deleteAll(tableName, idFieldName, eid.getId());
  }
bool ElementCacheLRU::containsElement(const ElementId& eid) const
{
  const ElementType::Type type = eid.getType().getEnum();
  const long id = eid.getId();

  switch ( type )
  {
  case ElementType::Node:
    if ( _nodes.find(id) != _nodes.end() )
    {
      return true;
    }

    break;

  case ElementType::Way:
    if ( _ways.find(id) != _ways.end() )
    {
      return true;
    }

    break;

  case ElementType::Relation:
    if ( _relations.find(id) != _relations.end() )
    {
      return true;
    }

    break;

  // Intentional fallthrow
  case ElementType::Unknown:
  default:

    break;
  }

  // If we get to this point, it meant we never found it
  return false;
}
void ReportMissingElementsVisitor::_reportMissing(ElementId referer, ElementId missing)
{
  if (_missingCount < _maxReport)
  {
    if (_removeMissing)
    {
      LOG_WARN("Removing missing " << missing.toString() << " in " <<
               referer.toString() << ".");
    }
    else
    {
      LOG_WARN("Missing " << missing.toString() << " in " <<
               referer.toString() << ".");
    }
  }
  _missingCount++;
  if (_missingCount == _maxReport)
  {
    LOG_WARN("Reached maximum number of missing reports. No longer reporting.");
  }
}
Example #11
0
 bool DefinedOn (ElementId id) const
 {
   if (id.IsBoundary())
     {
       if (!definedonbound.Size()) return true;
       return definedonbound[ma->GetSElIndex(int(id))];
     }
   else
     {
       if (!definedon.Size()) return true;
       return definedon[ma->GetElIndex(int(id))];
     }
 }
Example #12
0
void PlacesPoiMerger::apply(const OsmMapPtr& map, vector< pair<ElementId, ElementId> >& replaced)
  const
{
  set<ElementId> pois = getImpactedElementIds();

  // find the node with the best circular error.
  ElementId bestEid;
  Meters bestAcc = numeric_limits<Meters>::max();
  for (set<ElementId>::iterator it = pois.begin(); it != pois.end(); ++it)
  {
    ElementId eid = *it;

    const ConstNodePtr& n = map->getNode(eid.getId());
    if (n->getCircularError() < bestAcc || (n->getCircularError() == bestAcc && n->getStatus() == Status::Unknown1))
    {
      bestAcc = n->getCircularError();
      bestEid = eid;
    }
  }

  // the best circular error node becomes the geometry for the merger.
  const NodePtr& n = map->getNode(bestEid.getId());

  // grab the tags out of the best node.
  Tags tags = n->getTags();
  for (set<ElementId>::iterator it = pois.begin(); it != pois.end(); ++it)
  {
    ElementId eid = *it;

    // if this isn't the best node
    if (eid != bestEid)
    {
      // record that this ndoe is getting replaced.
      replaced.push_back(pair<ElementId, ElementId>(eid, bestEid));

      // use the default tag merging mechanism
      tags = _merger->mergeTags(tags, map->getNode(eid.getId())->getTags(), ElementType::Node);

      // if the POI has no parents, then simply remove it.
      if (map->getIndex().getParents(eid).size() == 0)
      {
        map->removeElement(eid);
      }
      // if the POI has parents, then remove all tags on the node.
      else
      {
        map->getNode(eid.getId())->getTags().clear();
      }
    }
  }

  n->setTags(tags);
  n->setStatus(Status::Conflated);
}
void RemoveDuplicateAreaVisitor::visit(const shared_ptr<Element>& e1)
{
  OsmSchema& schema = OsmSchema::getInstance();

  auto_ptr<Envelope> env(e1->getEnvelope(_map->shared_from_this()));
  // if the envelope is null or the element is incomplete.
  if (env->isNull() ||
      IsCompleteVisitor::isComplete(_map, e1->getElementId()) == false ||
      schema.isArea(e1) == false)
  {
    return;
  }
  set<ElementId> neighbors = _map->getIndex().findWayRelations(*env);

  for (set<ElementId>::const_iterator it = neighbors.begin(); it != neighbors.end(); ++it)
  {
    ElementId eit = *it;
    if (e1->getElementId() < eit && eit.getType() != ElementType::Node)
    {
      shared_ptr<Element> e2 = _map->getElement(*it);

      // check to see if e2 is null, it is possible that we removed it w/ a previous call to remove
      // a parent.
      if (e2 != 0 &&
          schema.isArea(e2) &&
          _equals(e1, e2))
      {
        // remove the crummier one.
        _removeOne(e1, e2);
        // if we've deleted the element we're visiting.
        if (_map->containsElement(e1) == false)
        {
          return;
        }
      }
    }
  }
}
Example #14
0
void ElementCacheLRU::removeElement(const ElementId &eid)
{
  switch ( eid.getType().getEnum() )
  {
  case ElementType::Node:
    _nodes.erase(_nodes.find(eid.getId()));
    break;

  case ElementType::Way:
    _ways.erase(_ways.find(eid.getId()));
    break;

  case ElementType::Relation:
    _relations.erase(_relations.find(eid.getId()));
    break;

  default:
    throw HootException("Invalid type passed");
    break;
  }

  resetElementIterators();
}
Example #15
0
set<ElementId> OsmMapIndex::getParents(ElementId eid) const
{
  set<ElementId> result;

  if (eid.getType() == ElementType::Node)
  {
    const set<long>& ways = getNodeToWayMap()->getWaysByNode(eid.getId());

    for (set<long>::const_iterator it = ways.begin(); it != ways.end(); ++it)
    {
      result.insert(ElementId::way(*it));
    }
  }

  const set<long>& ancestors = getElementToRelationMap()->getRelationByElement(eid);

  for (set<long>::const_iterator it = ancestors.begin(); it != ancestors.end(); ++it)
  {
    if (!_map.containsRelation(*it))
    {
      LOG_INFO("Child element: " << eid);
      LOG_INFO("Missing relation: " << *it);
      LOG_INFO("Child element: " << _map.getElement(eid)->toString());
    }
    // the map should contain all the relations returned by the index.
    assert(_map.containsRelation(*it));
    const shared_ptr<const Relation>& r = _map.getRelation(*it);

    if (r->contains(eid))
    {
      result.insert(r->getElementId());
    }
  }

  return result;
}
Example #16
0
void WayMergeManipulation::_removeSpans(OsmMapPtr map,
  set<ElementId>& impactedElements) const
{
  WayPtr left = map->getWay(_left);
  WayPtr right = map->getWay(_right);

  set<ElementId> impactedWaysTmp = impactedElements;
  for (set<ElementId>::iterator it = impactedWaysTmp.begin(); it != impactedWaysTmp.end(); ++it)
  {
    ElementId eid = *it;
    WayPtr w = map->getWay(eid.getId());
    long first = w->getNodeId(0);
    long last = w->getLastNodeId();
    if ((left->hasNode(first) && right->hasNode(last)) ||
        (left->hasNode(last) && right->hasNode(first)))
    {
      if (_directConnect(map, w))
      {
        RemoveWayOp::removeWay(map, eid.getId());
        impactedElements.erase(eid);
      }
    }
  }
}
Example #17
0
bool ScriptMatch::isConflicting(const Match& other, const ConstOsmMapPtr& map) const
{
  if (_neverCausesConflict)
  {
    return false;
  }

  bool conflicting = true;

  const ScriptMatch* hm = dynamic_cast<const ScriptMatch*>(&other);
  if (hm == 0)
  {
    return true;
  }
  if (hm == this)
  {
    return false;
  }

  // See ticket #5272
  if (getClassification().getReviewP() == 1.0 || other.getClassification().getReviewP() == 1.0)
  {
    return true;
  }

  ElementId sharedEid;
  if (_eid1 == hm->_eid1 || _eid1 == hm->_eid2)
  {
    sharedEid = _eid1;
  }

  if (_eid2 == hm->_eid1 || _eid2 == hm->_eid2)
  {
    // both eids should never be the same.
    assert(sharedEid.isNull());
    sharedEid = _eid2;
  }

  // if the matches don't share at least one eid then it isn't a conflict.
  if (sharedEid.isNull())
  {
    return false;
  }

  // assign o1 and o2 to the non-shared eids
  ElementId o1 = _eid1 == sharedEid ? _eid2 : _eid1;
  ElementId o2 = hm->_eid1 == sharedEid ? hm->_eid2 : hm->_eid1;

  bool foundCache = false;
  bool cacheConflict = false;
  QHash<ConflictKey, bool>::const_iterator cit1 = _conflicts.find(hm->_getConflictKey());
  if (cit1 != _conflicts.end())
  {
    foundCache = true;
    cacheConflict = cit1.value();
  }
  QHash<ConflictKey, bool>::const_iterator cit2 = hm->_conflicts.find(_getConflictKey());
  if (cit2 != hm->_conflicts.end())
  {
    foundCache = true;
    cacheConflict = cit2.value();
  }

  if (foundCache)
  {
    conflicting = cacheConflict;
  }
  else
  {
    try
    {
      // we need to check for a conflict in two directions. Is it conflicting if we merge the shared
      // EID with this class first, then is it a conflict if we merge with the other EID first.
      if (_isOrderedConflicting(map, sharedEid, o1, o2) ||
          hm->_isOrderedConflicting(map, sharedEid, o2, o1))
      {
        conflicting = true;
      }
      else
      {
        conflicting = false;
      }
    }
    catch (const NeedsReviewException& e)
    {
      conflicting = true;
    }
    _conflicts[hm->_getConflictKey()] = conflicting;
  }

  return conflicting;
}
Example #18
0
    void TransformVec (ElementId ei,
		       const T & vec, TRANSFORM_TYPE type) const
    {
      TransformVec (ei.Nr(), ei.IsBoundary(), vec, type);
    }
Example #19
0
 INLINE ElementIterator & operator++ ()
 {
   ++ei;
   while (ei.Nr() < fes.GetMeshAccess()->GetNE(VorB(ei)) && !fes.DefinedOn(ei)) ++ei;
   return *this;
 }
Example #20
0
void OsmApiDbReader::_processRelation(const QSqlQuery& resultIterator, OsmMap& map, const Envelope& env)
{
  QStringList tags;
  long long relId = resultIterator.value(0).toLongLong();

  vector<RelationData::Entry> members = _database.selectMembersForRelation( relId );
  for(vector<RelationData::Entry>::iterator it = members.begin(); it != members.end(); ++it)
  {
    ElementId eid = (*it).getElementId();
    QString type = eid.getType().toString();
    long idFromRelation = eid.getId();

    if(type=="Node")
    {
      shared_ptr<QSqlQuery> nodeIterator = _database.selectBoundedElements(idFromRelation, ElementType::Node, _bbox);
      if( nodeIterator->next() ) // we found a relation in the bounds
      {
        // process the relation into a data structure
        shared_ptr<Element> element = _resultToRelation(resultIterator, map);

        // get the way tags
        shared_ptr<QSqlQuery> relationTagIterator = _database.selectTagsForRelation( relId );
        while( relationTagIterator->next() )
        {
          // test for blank tag
          QString val1 = relationTagIterator->value(1).toString();
          QString val2 = relationTagIterator->value(2).toString();
          QString tag = "";
          if(val1!="" || val2!="") tag = "\""+val1+"\"=>\""+val2+"\"";
          if(tag != "") tags << tag;
        }
        if(tags.size()>0)
        {
          element->setTags(ApiDb::unescapeTags(tags.join(", ")) );
          ApiDbReader::addTagsToElement( element );
        }

        if (_status != Status::Invalid) {element->setStatus(_status); }
        map.addElement(element);
        tags.clear();
      }
    }
    else if(type == "Way")
    {
      shared_ptr<QSqlQuery> nodeInfoIterator = _database.selectNodesForWay( idFromRelation );
      bool foundOne = false;
      while( nodeInfoIterator->next() && !foundOne)
      {
        // do the bounds check
        double lat = nodeInfoIterator->value(ApiDb::NODES_LATITUDE).toLongLong()/(double)ApiDb::COORDINATE_SCALE;
        double lon = nodeInfoIterator->value(ApiDb::NODES_LONGITUDE).toLongLong()/(double)ApiDb::COORDINATE_SCALE;
        Coordinate c(lon, lat);
        if (env.contains(c))
        {
          foundOne = true;
        }
      }
      if( foundOne ) // we found a relation in the bounds
      {
        // process the relation into a data structure
        shared_ptr<Element> element = _resultToRelation(resultIterator, map);

        // get the way tags
        shared_ptr<QSqlQuery> relationTagIterator = _database.selectTagsForRelation( relId );
        while( relationTagIterator->next() )
        {
          // test for blank tag
          QString val1 = relationTagIterator->value(1).toString();
          QString val2 = relationTagIterator->value(2).toString();
          QString tag = "";
          if(val1!="" || val2!="") tag = "\""+val1+"\"=>\""+val2+"\"";
          if(tag != "") tags << tag;
        }
        if(tags.size()>0)
        {
          element->setTags( ApiDb::unescapeTags(tags.join(", ")) );
          ApiDbReader::addTagsToElement( element );
        }

        if (_status != Status::Invalid) { element->setStatus(_status); }
        map.addElement(element);
        tags.clear();
      }
    }
    else if(type == "Relation")
    {
      shared_ptr<QSqlQuery> relIterator = _database.selectBoundedElements(idFromRelation, ElementType::Relation, _bbox);
      while(relIterator->next())
      {
        _processRelation(*relIterator, map, env);
      }
    }
  }
}
Example #21
0
void PbfReader::_loadRelation(const hoot::pb::Relation& r)
{
  long newId = _createRelationId(r.id());

  shared_ptr<hoot::Relation> newRelation(new hoot::Relation(_status, newId, _circularError));


  if (r.roles_sid_size() != r.memids_size() || r.roles_sid_size() != r.types_size())
  {
    LOG_WARN("roles_sid size, memids size or types size don't match."
             << " roles_sid size: " << r.roles_sid_size()
             << " memids size: " << r.memids_size()
             << " types size: " << r.types_size());
  }
  int membersSize = std::min(r.roles_sid_size(), std::min(r.memids_size(), r.types_size()));

  long mid = 0;

  for (int i = 0; i < membersSize; i++)
  {
    int sid = r.roles_sid().Get(i);
    mid += r.memids().Get(i);
    int type = r.types().Get(i);
    QString role;
    if ((size_t)sid < _strings.size() && sid >= 0)
    {
      role = _strings[sid];
    }
    else
    {
      LOG_WARN("Relation SID was out of bounds: " << sid << " size: " << _strings.size());
    }

    ElementId eid = _convertToElementId(mid, type);

    if (eid.getType() != ElementType::Unknown)
    {
      newRelation->addElement(role, eid);
    }
  }

  if (r.keys().size() != r.vals().size())
  {
    LOG_WARN("Key and value arrays are not the same size. (" << r.keys().size() << " vs. " <<
             r.vals().size() << " way id: " << r.id() << ")");
  }

  for (int i = 0; i < r.keys().size() && i < r.vals().size(); i++)
  {
    if (r.keys().Get(i) >= _strings.size())
    {
      LOG_WARN("Key was out of bounds: " << r.keys().Get(i) << " size: " << _strings.size());
    }
    else if (r.vals().Get(i) >= _strings.size())
    {
      LOG_WARN("Value was out of bounds: " << r.vals().Get(i) << " size: " << _strings.size());
    }
    else
    {
      QString key = _strings[r.keys().Get(i)];
      QString value = _strings[r.vals().Get(i)];

      _addTag(newRelation, key, value);
    }
  }

  _parseTimestamp(r.info(), newRelation->getTags());

  if (_map->containsRelation(newId))
  {
    LOG_WARN("Map already contains relation: " << newId);
  }
  _map->addRelation(newRelation);
}
void ServicesDbWriter::writePartial(const shared_ptr<const Relation>& r)
{
  long relationId;

  //LOG_DEBUG("Inside writePartial for Relation");

  Tags tags = r->getTags();
  if ( _sdb.getDatabaseType() == ServicesDb::DBTYPE_SERVICES)
  {
    _addElementTags(r, tags);
  }

  if (!r->getType().isEmpty())
  {
    tags["type"] = r->getType();
  }

  if (_remapIds)
  {
    relationId = _getRemappedElementId(r->getElementId());

    LOG_DEBUG("Inserting relation with source ID = " <<
              QString::number(r->getId()) << " which maps to DB ID = " <<
              QString::number(relationId) );

      _sdb.insertRelation(relationId, tags);
  }
  else
  {
    if (r->getId() < 1)
    {
      throw HootException("Non-positive IDs are not supported by ServicesDbWriter without remapping");
    }

    _sdb.insertRelation(r->getId(), tags);
    relationId = r->getId();
  }

  Tags emptyTags;
  for (size_t i = 0; i < r->getMembers().size(); ++i)
  {
    RelationData::Entry e = r->getMembers()[i];

    // May need to create new ID mappings for items we've not yet seen
    ElementId relationMemberElementId = e.getElementId();

    if ( _remapIds == true )
    {
      relationMemberElementId = ElementId(relationMemberElementId.getType(),
        _getRemappedElementId(relationMemberElementId));
    }

    _sdb.insertRelationMember(relationId, relationMemberElementId.getType(),
                              relationMemberElementId.getId(), e.role, i);
  }

  //LOG_DEBUG("All members added to relation " << QString::number(relationId));

  _countChange();

  //LOG_DEBUG("Leaving relation write cleanly");

  _relationsWritten++;
}
Example #23
0
PoiPolygonMatch::PoiPolygonMatch(const ConstOsmMapPtr& map, const ElementId& eid1,
                                 const ElementId& eid2, ConstMatchThresholdPtr threshold) :
Match(threshold)
{
  ConstElementPtr e1 = map->getElement(eid1);
  ConstElementPtr e2 = map->getElement(eid2);
  ConstElementPtr poi, poly;
  if (isPoiIsh(e1) && isBuildingIsh(e2))
  {
    _poiEid = eid1;
    _polyEid = eid2;
    poi = e1;
    poly = e2;
  }
  else if (isPoiIsh(e2) && isBuildingIsh(e1))
  {
    _poiEid = eid2;
    _polyEid = eid1;
    poi = e2;
    poly = e1;
  }
  else
  {
    LOG_WARN(e1->toString());
    LOG_WARN(e2->toString());
    throw IllegalArgumentException("Expected a POI & polygon, got: " + eid1.toString() + " " +
                                   eid2.toString());
  }

  shared_ptr<Geometry> gpoly = ElementConverter(map).convertToGeometry(poly);
  shared_ptr<Geometry> gpoi = ElementConverter(map).convertToGeometry(poi);

  bool typeMatch = _calculateTypeMatch(poi, poly);
  double nameScore = _calculateNameScore(poi, poly);
  bool nameMatch = nameScore >= ConfigOptions().getPoiPolygonMatchNameThreshold();
  double distance = gpoly->distance(gpoi.get());

  // calculate the 2 sigma for the distance between the two objects
  double sigma1 = e1->getCircularError() / 2.0;
  double sigma2 = e1->getCircularError() / 2.0;
  double ce = sqrt(sigma1 * sigma1 + sigma2 * sigma2) * 2;

  double reviewDistance = ConfigOptions().getPoiPolygonMatchReviewDistance() + ce;
  bool closeMatch = distance <= reviewDistance;

  int evidence = 0;
  evidence += typeMatch ? 1 : 0;
  evidence += nameMatch ? 1 : 0;
  evidence += distance == 0 ? 2 : 0;

  if (!closeMatch)
  {
    _c.setMiss();
  }
  else if (evidence >= 3)
  {
    _c.setMatch();
  }
  else if (evidence >= 1)
  {
    _c.setReview();
  }
  else
  {
    _c.setMiss();
  }
}
Example #24
0
int NodeMatcher::getDegree(ElementId nid)
{
  return (int)_map->getIndex().getNodeToWayMap()->at(nid.getId()).size();
}
long ServicesDbWriter::_getRemappedElementId(const ElementId& eid)
{
  if (_remapIds == false)
  {
    return eid.getId();
  }

  long retVal = -1;

  switch(eid.getType().getEnum())
  {
  case ElementType::Node:
    if (_nodeRemap.count(eid.getId()) == 1)
    {
      retVal = _nodeRemap.at(eid.getId());
    }
    else
    {
      retVal = _sdb.reserveElementId(ElementType::Node);
      _nodeRemap[eid.getId()] = retVal;
      if ( _outputMappingFile.length() > 0 )
      {
        _sourceNodeIds.insert(eid.getId());
      }
    }

    break;

  case ElementType::Way:
    if (_wayRemap.count(eid.getId()) == 1)
    {
      retVal = _wayRemap.at(eid.getId());
    }
    else
    {
      retVal = _sdb.reserveElementId(ElementType::Way);
      _wayRemap[eid.getId()] = retVal;
      if ( _outputMappingFile.length() > 0 )
      {
        _sourceWayIds.insert(eid.getId());
      }
    }

    break;

  case ElementType::Relation:
    if (_relationRemap.count(eid.getId()) == 1)
    {
      retVal = _relationRemap.at(eid.getId());
      /*
      LOG_DEBUG("Returning established relation ID mapping, source ID = " <<
        QString::number(eid.getId()) << ", database ID = " <<
        QString::number(_relationRemap.at(eid.getId())) );
      */
    }
    else
    {
      retVal = _sdb.reserveElementId(ElementType::Relation);
      _relationRemap[eid.getId()] = retVal;
      if ( _outputMappingFile.length() > 0 )
      {
        _sourceRelationIds.insert(eid.getId());
      }

      /*
      LOG_DEBUG("Established new relation ID mapping, source ID = " <<
        QString::number(eid.getId()) << ", database ID = " <<
        QString::number(_relationRemap.at(eid.getId())) );
      */
    }

    break;

  default:
    LOG_ERROR("Tried to create or remap ID for invalid type");
    throw NotImplementedException();

    break;
  }

  return retVal;
}