void verifyFullReadOutput(OsmMapPtr map)
  {
    //nodes
    CPPUNIT_ASSERT_EQUAL(2, (int)map->getNodes().size());
    HOOT_STR_EQUALS(true, map->containsNode(1));
    NodePtr node = map->getNode(1);
    CPPUNIT_ASSERT_EQUAL((long)1, node->getId());
    CPPUNIT_ASSERT_EQUAL(38.4, node->getY());
    CPPUNIT_ASSERT_EQUAL(-106.5, node->getX());
    CPPUNIT_ASSERT_EQUAL(15.0, node->getCircularError());
    CPPUNIT_ASSERT_EQUAL(2, node->getTags().size());

    NodePtr node1 = map->getNode(2);
    CPPUNIT_ASSERT_EQUAL((long)2, node1->getId());
    CPPUNIT_ASSERT_EQUAL(38.0, node1->getY());
    CPPUNIT_ASSERT_EQUAL(-104.0, node1->getX());

    //ways
    HOOT_STR_EQUALS(true, map->containsWay(1));
    WayPtr way = map->getWay(1);
    CPPUNIT_ASSERT_EQUAL((long)1, way->getId());
    CPPUNIT_ASSERT_EQUAL(2, (int)way->getNodeCount());
    CPPUNIT_ASSERT_EQUAL((long)1, way->getNodeId(0));
    CPPUNIT_ASSERT_EQUAL((long)2, way->getNodeId(1));
    CPPUNIT_ASSERT_EQUAL(15.0, way->getCircularError());
    CPPUNIT_ASSERT_EQUAL(1, way->getTags().size());

    //relations
    HOOT_STR_EQUALS(true, map->containsRelation(1));
    RelationPtr relation = map->getRelation(1);
    CPPUNIT_ASSERT_EQUAL((long)1, relation->getId());
    vector<RelationData::Entry> relationData = relation->getMembers();
    CPPUNIT_ASSERT_EQUAL(2, (int)relation->getMembers().size());
    HOOT_STR_EQUALS("wayrole", relationData[0].getRole());
    HOOT_STR_EQUALS("noderole",relationData[1].getRole());
    CPPUNIT_ASSERT_EQUAL(15.0, relation->getCircularError());
  }
Example #2
0
void WayMergeManipulation::applyManipulation(OsmMapPtr map,
  set<ElementId> &impactedElements, set<ElementId> &newElements) const
{
  OsmMapPtr result = map;

  // insert the impacted ways
  impactedElements = getImpactedElementIds(map);
  impactedElements.erase(ElementId::way(_left));
  impactedElements.erase(ElementId::way(_right));

  // remove any ways that spanned the left & right
  _removeSpans(result, impactedElements);

  WayPtr left = result->getWay(_left);
  WayPtr right = result->getWay(_right);

  Meters minSplitSize = _minSplitSize;
  minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(left)->getLength() * .7);
  minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(right)->getLength() * .7);

  // split left into its maximal nearest sublines
  MaximalNearestSubline mns1(map, left, right, minSplitSize,
    left->getCircularError() + right->getCircularError());
  int mnsLeftIndex;
  vector< WayPtr > splitsLeft = mns1.splitWay(result, mnsLeftIndex);
  assert(splitsLeft.size() != 0);
  WayPtr mnsLeft = splitsLeft[mnsLeftIndex];

  // split right into its maximal nearest sublines
  MaximalNearestSubline mns2(map, right, mnsLeft, minSplitSize,
    left->getCircularError() + right->getCircularError());
  int mnsRightIndex;
  vector< WayPtr > splitsRight = mns2.splitWay(result, mnsRightIndex);
  assert(splitsRight.size() != 0);
  WayPtr mnsRight = splitsRight[mnsRightIndex];

  for (size_t i = 0; i < splitsLeft.size(); i++)
  {
    if ((int)i != mnsLeftIndex)
    {
      newElements.insert(ElementId::way(splitsLeft[i]->getId()));
    }
    result->addWay(splitsLeft[i]);
  }

  for (size_t i = 0; i < splitsRight.size(); i++)
  {
    if ((int)i != mnsRightIndex)
    {
      newElements.insert(ElementId::way(splitsRight[i]->getId()));
    }
    result->addWay(splitsRight[i]);
  }

  // average the two MNSs
  WayPtr w = WayAverager::average(map, mnsRight, mnsLeft);
  w->setStatus(Status::Conflated);

  RemoveWayOp::removeWay(result, _left);
  RemoveWayOp::removeWay(result, _right);

  result->addWay(w);

  // insert the new merged way
  newElements.insert(ElementId::way(w->getId()));

  for (set<ElementId>::iterator it = impactedElements.begin(); it != impactedElements.end(); ++it)
  {
    if (result->containsElement(*it) == false)
    {
      LOG_ERROR("" << "Internal error: bad way " << it->toString());
    }
  }
}
  void _sanityCheckSplit(SplitLongLinearWaysVisitor& /*splitVisitor*/, const int startNode,
                         const int numNodes, const int numWays)
  {
    // Pull out ways
    WayMap ways = _map->getWays();
    CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(numWays), ways.size() );

    // Pull out nodes
    OsmMap::NodeMap nodes = _map->getNodeMap();
    CPPUNIT_ASSERT_EQUAL( numNodes, nodes.size() );

    // Make sure no relations
    RelationMap relations = _map->getRelationMap();
    CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(0), relations.size() );

    unsigned int nodesLeftToFind = numNodes;
    unsigned int searchId = startNode;
    while ( nodesLeftToFind > 0 )
    {
      LOG_DEBUG("Looking for node ID " << searchId);
      bool madeProgress = false;
      bool hitError = false;
      for (WayMap::const_iterator it = ways.begin(); it != ways.end(); it++)
      {
        // Does this way have the node we're looking for?
        WayPtr currWay = it->second;

        if ( currWay->getFirstNodeId() == searchId )
        {
          nodesLeftToFind--;
          LOG_DEBUG("Found node ID " << searchId << " at start of way " <<
                     currWay->getId());
          madeProgress = true;
          // Make sure rest of nodes we want exist and are in correct order
          searchId++;
          std::vector<long> wayIds = currWay->getNodeIds();

          // Start at second node, since we already checked first one
          for ( std::vector<long>::const_iterator nodeIt = wayIds.begin() + 1;
            nodeIt != wayIds.end(); ++nodeIt )
          {
             if ( *nodeIt != searchId )
             {
               // Throw a hissy fit
               hitError = true;
               break;
             }

             nodesLeftToFind--;
             searchId++;
          }
          searchId--;
          // Search count is off by one
          if ( nodesLeftToFind > 0 )
          {
            nodesLeftToFind++;
          }

          LOG_DEBUG("Found remainder of IDs up to " << searchId << " inside way");
          LOG_DEBUG("Nodes left to find: " << nodesLeftToFind);

          // We found what we needed, bail out of looking for more ways
          break;
        }
        else
        {
          LOG_DEBUG("Way started with ID " << currWay->getFirstNodeId() << ", skipping");
        }
      }

      CPPUNIT_ASSERT( (madeProgress == true) && (hitError == false) );
    }
  }
  void runPartialReadTest()
  {
    //The differences in tag counts here when compared to
    //ServiceHootApiDbReaderTest::runPartialReadTest are due to differences between the way
    //HootApiDbWriter and OsmApiDbBulkInserter handle metadata tags, which is by design.

    populatePartialMap();

    OsmApiDbReader reader;
    const int chunkSize = 3;
    reader.setMaxElementsPerMap(chunkSize);
    reader.open(ServicesDbTestUtils::getOsmApiDbUrl().toString());
    reader.initializePartial();

    int ctr = 0;
    OsmMapPtr map(new OsmMap());

    //3 nodes

    CPPUNIT_ASSERT(reader.hasMoreElements());
    reader.readPartial(map);
    CPPUNIT_ASSERT_EQUAL(3, (int)map->getNodes().size());
    CPPUNIT_ASSERT_EQUAL(0, (int)map->getWays().size());
    CPPUNIT_ASSERT_EQUAL(0, (int)map->getRelations().size());

    NodePtr node = map->getNode(1);
    CPPUNIT_ASSERT_EQUAL((long)1, node->getId());
    CPPUNIT_ASSERT_EQUAL(0.0, node->getX());
    CPPUNIT_ASSERT_EQUAL(0.0, node->getY());
    CPPUNIT_ASSERT_EQUAL(0, node->getTags().size());

    node = map->getNode(2);
    CPPUNIT_ASSERT_EQUAL((long)2, node->getId());
    CPPUNIT_ASSERT_EQUAL(0.1, node->getX());
    CPPUNIT_ASSERT_EQUAL(0.0, node->getY());
    CPPUNIT_ASSERT_EQUAL(1, node->getTags().size());
    HOOT_STR_EQUALS("n2b", node->getTags().get("noteb"));

    node = map->getNode(3);
    CPPUNIT_ASSERT_EQUAL((long)3, node->getId());
    CPPUNIT_ASSERT_EQUAL(0.2, node->getX());
    CPPUNIT_ASSERT_EQUAL(0.0, node->getY());
    CPPUNIT_ASSERT_EQUAL(1, node->getTags().size());
    HOOT_STR_EQUALS("n3", node->getTags().get("note"));

    ctr++;

    //2 nodes, 1 way

    map.reset(new OsmMap());
    CPPUNIT_ASSERT(reader.hasMoreElements());
    reader.readPartial(map);
    CPPUNIT_ASSERT_EQUAL(2, (int)map->getNodes().size());
    CPPUNIT_ASSERT_EQUAL(1, (int)map->getWays().size());
    CPPUNIT_ASSERT_EQUAL(0, (int)map->getRelations().size());

    node = map->getNode(4);
    CPPUNIT_ASSERT_EQUAL((long)4, node->getId());
    CPPUNIT_ASSERT_EQUAL(0.3, node->getX());
    CPPUNIT_ASSERT_EQUAL(0.0, node->getY());
    CPPUNIT_ASSERT_EQUAL(1, node->getTags().size());
    HOOT_STR_EQUALS("n4", node->getTags().get("note"));

    node = map->getNode(5);
    CPPUNIT_ASSERT_EQUAL((long)5, node->getId());
    CPPUNIT_ASSERT_EQUAL(0.4, node->getX());
    CPPUNIT_ASSERT_EQUAL(0.0, node->getY());
    CPPUNIT_ASSERT_EQUAL(0, node->getTags().size());

    WayPtr way = map->getWay(1);
    CPPUNIT_ASSERT_EQUAL((long)1, way->getId());
    CPPUNIT_ASSERT(way->hasNode(1));
    CPPUNIT_ASSERT(way->hasNode(2));
    CPPUNIT_ASSERT_EQUAL(1, way->getTags().size());
    HOOT_STR_EQUALS("w1b", way->getTags().get("noteb"));

    ctr++;

    //2 ways, 1 relation

    map.reset(new OsmMap());
    CPPUNIT_ASSERT(reader.hasMoreElements());
    reader.readPartial(map);
    CPPUNIT_ASSERT_EQUAL(0, (int)map->getNodes().size());
    CPPUNIT_ASSERT_EQUAL(2, (int)map->getWays().size());
    CPPUNIT_ASSERT_EQUAL(1, (int)map->getRelations().size());

    way = map->getWay(2);
    CPPUNIT_ASSERT_EQUAL((long)2, way->getId());
    CPPUNIT_ASSERT(way->hasNode(2));
    CPPUNIT_ASSERT(way->hasNode(3));
    CPPUNIT_ASSERT_EQUAL(1, way->getTags().size());
    HOOT_STR_EQUALS("w2", way->getTags().get("note"));

    way = map->getWay(3);
    CPPUNIT_ASSERT_EQUAL((long)3, way->getId());
    CPPUNIT_ASSERT(way->hasNode(2));
    CPPUNIT_ASSERT_EQUAL(0, way->getTags().size());

    RelationPtr relation = map->getRelation(1);
    CPPUNIT_ASSERT_EQUAL((long)1, relation->getId());
    CPPUNIT_ASSERT_EQUAL(size_t(2), relation->getMembers().size());
    CPPUNIT_ASSERT(relation->contains(ElementId::node(1)));
    CPPUNIT_ASSERT(relation->contains(ElementId::way(1)));
    RelationData::Entry member = relation->getMembers().at(0);
    HOOT_STR_EQUALS("n1", member.role);
    CPPUNIT_ASSERT_EQUAL((long)1, member.getElementId().getId());
    member = relation->getMembers().at(1);
    HOOT_STR_EQUALS("w1", member.role);
    CPPUNIT_ASSERT_EQUAL((long)1, member.getElementId().getId());
    CPPUNIT_ASSERT_EQUAL(1, relation->getTags().size());
    HOOT_STR_EQUALS("r1", relation->getTags().get("note"));

    ctr++;

    //1 relation

    map.reset(new OsmMap());
    CPPUNIT_ASSERT(reader.hasMoreElements());
    reader.readPartial(map);
    CPPUNIT_ASSERT_EQUAL(0, (int)map->getNodes().size());
    CPPUNIT_ASSERT_EQUAL(0, (int)map->getWays().size());
    CPPUNIT_ASSERT_EQUAL(1, (int)map->getRelations().size());

    relation = map->getRelation(2);
    CPPUNIT_ASSERT_EQUAL((long)2, relation->getId());
    HOOT_STR_EQUALS("", relation->getType());
    CPPUNIT_ASSERT(relation->contains(ElementId::node(2)));
    CPPUNIT_ASSERT_EQUAL(size_t(1), relation->getMembers().size());
    member = relation->getMembers().at(0);
    HOOT_STR_EQUALS("n2", member.role);
    CPPUNIT_ASSERT_EQUAL((long)2, member.getElementId().getId());
    CPPUNIT_ASSERT_EQUAL(0, relation->getTags().size());

    ctr++;

    CPPUNIT_ASSERT(!reader.hasMoreElements());
    reader.finalizePartial();

    CPPUNIT_ASSERT_EQUAL(4, ctr);
  }