void runConflateTest() { OsmReader reader; shared_ptr<OsmMap> map(new OsmMap()); reader.setDefaultStatus(Status::Unknown1); reader.read("test-files/ToyBuildingsTestA.osm", map); reader.setDefaultStatus(Status::Unknown2); reader.read("test-files/ToyBuildingsTestB.osm", map); MapProjector::projectToPlanar(map); WayMap wm = map->getWays(); for (WayMap::const_iterator it = wm.begin(); it != wm.end(); ++it) { const ConstWayPtr& w = it->second; const Tags& t = w->getTags(); if (t["REF1"] != "Target" && t["REF2"] != "Target") { map->removeWay(it->first); } } Conflator uut; shared_ptr<Manipulator> m(new BuildingMergeManipulator()); deque< shared_ptr<Manipulator> > manipulators; manipulators.push_back(m); uut.setManipulators(manipulators); uut.loadSource(map); uut.conflate(); shared_ptr<OsmMap> out(new OsmMap(uut.getBestMap())); MapProjector::projectToWgs84(out); OsmWriter writer; writer.setIncludeIds(true); writer.write(out, "test-output/BuildingConflatorTest.osm"); ConstWayPtr cheddars = getWay(out, "REF1", "Cheddar's"); CPPUNIT_ASSERT_EQUAL(string("Cheddar's"), cheddars->getTags()["REF2"].toStdString()); HOOT_STR_EQUALS(Status::Conflated, cheddars->getStatus()); ConstWayPtr biondi = getWay(out, "REF1", "Biondi"); CPPUNIT_ASSERT_EQUAL(string("Biondi"), biondi->getTags()["REF2"].toStdString()); HOOT_STR_EQUALS(Status::Conflated, biondi->getStatus()); ConstWayPtr freddys = getWay(out, "REF1", "Freddy's"); CPPUNIT_ASSERT_EQUAL(false, freddys->getTags().contains("REF2")); HOOT_STR_EQUALS(Status::Unknown1, freddys->getStatus()); ConstWayPtr target = getWay(out, "REF1", "Target"); CPPUNIT_ASSERT_EQUAL(string("Target"), biondi->getTags()["REF2"].toStdString()); HOOT_STR_EQUALS(Status::Unknown1, target->getStatus()); CPPUNIT_ASSERT_EQUAL((size_t)9, out->getWays().size()); }
void SuperfluousWayRemover::removeWays() { LOG_INFO("Removing superfluous ways..."); shared_ptr<ElementToRelationMap> e2r = _inputMap->getIndex().getElementToRelationMap(); // make a copy of the ways to avoid issues when removing. const WayMap ways = _inputMap->getWays(); for (WayMap::const_iterator it = ways.begin(); it != ways.end(); ++it) { const shared_ptr<const Way>& w = it->second; bool same = true; long firstId; const vector<long>& nodeIds = w->getNodeIds(); if (nodeIds.size() > 0) { firstId = nodeIds[0]; for (size_t i = 1; i < nodeIds.size(); i++) { if (nodeIds[i] != firstId) { same = false; } } } bool inRelation = e2r->getRelationByElement(w).size() > 0; // if all the nodes in a way are the same or there are zero nodes if ((same || w->getTags().size() == 0) && !inRelation) { _inputMap->removeWayFully(w->getId()); } } }
std::map<unsigned long long int, std::pair<RelationPtr, std::map<unsigned long long int, WayPtr> > > Network::getWaysByAdminBoundary(int admin_level) { typedef std::map<unsigned long long int, WayPtr> WayMap; typedef std::pair<unsigned long long int, WayPtr> WayType; typedef std::map<unsigned long long int, RelationPtr> RelationMap; typedef std::pair<RelationPtr, WayMap> RelationWayPair; typedef std::map<unsigned long long int, RelationWayPair> GlobalMap; GlobalMap ret; util::Log::GetInstance().info("extracting administrative boundaries"); RelationMap adminBoundaries = getAdministrativeBoundaries(admin_level); util::Log::GetInstance().info("finished extracting administrative boundaries"); WayMap waysList; BOOST_FOREACH(WayType w, ways) { if( w.second->getNodes()->size() > 1 && w.second->hasTag(Element::TAG_HIGHWAY) && Way::highwayTypes.find(w.second->getTag(Element::TAG_HIGHWAY)) != Way::highwayTypes.end() ) { waysList[w.second->getId()] = w.second; } } util::Log::GetInstance().info("extracting ways by administrative boundaries"); RelationMap::iterator boundaryIterator = adminBoundaries.begin(); while(boundaryIterator != adminBoundaries.end()) { RelationPtr boundary = boundaryIterator->second; ret[boundaryIterator->first] = RelationWayPair(boundary, WayMap()); boundaryIterator++; } WayMap::iterator wayIterator = waysList.begin(); while(wayIterator != waysList.end()) { WayPtr way = wayIterator->second; boost::shared_ptr<const geos::geom::Geometry> wayGeom = way->toGeometry(); boundaryIterator = adminBoundaries.begin(); while(boundaryIterator != adminBoundaries.end()) { RelationPtr boundary = boundaryIterator->second; boost::shared_ptr<const geos::geom::prep::PreparedGeometry> boundaryPrepGeom = boundary->toPreparedGeometry(); if(boundaryPrepGeom->covers(wayGeom.get()) || boundaryPrepGeom->intersects(wayGeom.get())) { //the way is inside or intersected by the boundary, keep it ret[boundaryIterator->first].second[wayIterator->first] = way; //mark the nodes of this way for next step reference counting way->referenceWithNodes(); break; } else //no interaction with current boundary boundaryIterator++; } ++wayIterator; } util::Log::GetInstance().info("finished extracting ways by administrative boundaries"); return ret; }
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 MapCropper::apply(shared_ptr<OsmMap>& map) { LOG_INFO("Cropping map."); shared_ptr<OsmMap> result = map; if (MapReprojector::isGeographic(map) == false && _nodeBounds.isNull() == false) { throw HootException("If the node bounds is set the projection must be geographic."); } // @todo visit the elements from the most senior (e.g. relation that has no parents) to the // most junior (nodes). // go through all the ways const WayMap ways = result->getWays(); for (WayMap::const_iterator it = ways.begin(); it != ways.end(); it++) { const shared_ptr<Way>& w = it->second; shared_ptr<LineString> ls = ElementConverter(map).convertToLineString(w); const Envelope& e = *(ls->getEnvelopeInternal()); // if the way is completely outside the region we're keeping if (_isWhollyOutside(e)) { // remove the way result->removeWayFully(w->getId()); } else if (_isWhollyInside(e)) { // keep the way } else { // do an expensive operation to decide how much to keep, if any. _cropWay(result, w->getId()); } } shared_ptr<NodeToWayMap> n2wp = result->getIndex().getNodeToWayMap(); NodeToWayMap& n2w = *n2wp; LOG_INFO(" Removing nodes..."); // go through all the nodes const OsmMap::NodeMap nodes = result->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nodes.constBegin(); it != nodes.constEnd(); it++) { const Coordinate& c = it.value()->toCoordinate(); bool nodeInside = false; if (_envelope.isNull() == false) { if (_invert == false) { nodeInside = _envelope.covers(c); } else { nodeInside = !_envelope.covers(c); } } else { auto_ptr<Point> p(GeometryFactory::getDefaultInstance()->createPoint(c)); if (_invert == false) { nodeInside = _envelopeG->intersects(p.get()); } else { nodeInside = !_envelopeG->intersects(p.get()); } } // if the node is outside if (!nodeInside) { // if the node is within the limiting bounds. if (_nodeBounds.isNull() == true || _nodeBounds.contains(c)) { // if the node is not part of a way if (n2w.find(it.key()) == n2w.end()) { // remove the node result->removeNodeNoCheck(it.value()->getId()); } } } } RemoveEmptyRelationsVisitor v; map->visitRw(v); }