static void getMatches(const NGHolder &g, MatchSet &matches, struct fmstate &state, bool allowEodMatches) { SOMMap::const_iterator it, ite; for (it = state.states.begin(), ite = state.states.end(); it != ite; ++it) { NFAGraph::adjacency_iterator ai, ae; // we can't accept anything from startDs inbetween UTF-8 codepoints if (state.utf8 && it->first == g.startDs && !isUtf8CodePoint(state.cur)) { continue; } for (tie(ai, ae) = adjacent_vertices(it->first, g); ai != ae; ++ai) { if (*ai == g.accept || (*ai == g.acceptEod && allowEodMatches)) { // check edge assertions if we are allowed to reach accept if (!canReach(g, it->first, *ai, state)) { continue; } DEBUG_PRINTF("match found at %zu\n", state.offset); assert(!g[it->first].reports.empty()); for (const auto &report_id : g[it->first].reports) { const Report &ri = state.rm.getReport(report_id); DEBUG_PRINTF("report %u has offset adjustment %d\n", report_id, ri.offsetAdjust); matches.insert( make_pair(it->second, state.offset + ri.offsetAdjust)); } } } } }
/** * Creates a single match and should result in a PoiPolygonMerger */ void basicTest() { OsmMap::resetCounters(); OsmMapPtr map(new OsmMap()); Coordinate c1[] = { Coordinate(0.0, 0.0), Coordinate(20.0, 0.0), Coordinate(20.0, 20.0), Coordinate(0.0, 20.0), Coordinate(0.0, 0.0), Coordinate::getNull() }; WayPtr w1 = TestUtils::createWay(map, Status::Unknown1, c1, 5, "w1"); w1->getTags().set("area", true); w1->getTags()["name"] = "foo"; w1->getTags()["amenity"] = "bar"; NodePtr n1(new Node(Status::Unknown2, 1, 10, 10, 5)); n1->getTags()["name"] = "bar"; n1->getTags()["amenity"] = "cafe"; map->addNode(n1); PoiPolygonMatch match1( map, w1->getElementId(), n1->getElementId(), shared_ptr<MatchThreshold>()); MatchSet matches; matches.insert(&match1); vector<Merger*> mergers; PoiPolygonMergerCreator uut; uut.setOsmMap(map.get()); HOOT_STR_EQUALS(1, uut.createMergers(matches, mergers)); HOOT_STR_EQUALS(1, mergers.size()); HOOT_STR_EQUALS(1, (dynamic_cast<PoiPolygonMerger*>(mergers[0]) != 0)); }
/** * Creates two matches with overlap and should create a MarkForReviewMerger */ void reviewTest() { OsmMap::resetCounters(); OsmMapPtr map(new OsmMap()); Coordinate c1[] = { Coordinate(0.0, 0.0), Coordinate(20.0, 0.0), Coordinate(20.0, 20.0), Coordinate(0.0, 20.0), Coordinate(0.0, 0.0), Coordinate::getNull() }; WayPtr w1 = TestUtils::createWay(map, Status::Unknown1, c1, 5, "w1"); w1->getTags().set("building", true); w1->getTags()["name"] = "foo"; w1->getTags()["amenity"] = "bar"; Coordinate c2[] = { Coordinate(0.0, 0.0), Coordinate(5.0, 0.0), Coordinate(5.0, 5.0), Coordinate(0.0, 5.0), Coordinate(0.0, 0.0), Coordinate::getNull() }; WayPtr w2 = TestUtils::createWay(map, Status::Unknown2, c2, 5, "w2"); w2->getTags().set("building", true); w2->getTags()["name"] = "goofie"; NodePtr n1(new Node(Status::Unknown2, 1, 19, 19, 5)); n1->getTags()["name"] = "foo"; n1->getTags()["amenity"] = "cafe"; map->addNode(n1); vector<const Match*> matchesV; PoiPolygonMatch match1(map, w1->getElementId(), n1->getElementId(), shared_ptr<MatchThreshold>()); matchesV.push_back(&match1); shared_ptr<const MatchThreshold> threshold(new MatchThreshold(0.5, 0.5, 0.5)); BuildingMatchCreator().createMatches(map, matchesV, threshold); PoiPolygonMatch match2(map, w2->getElementId(), n1->getElementId(), shared_ptr<MatchThreshold>()); LOG_VAR(match2); MatchSet matches; matches.insert(matchesV.begin(), matchesV.end()); vector<Merger*> mergers; PoiPolygonMergerCreator uut; uut.setOsmMap(map.get()); HOOT_STR_EQUALS(1, uut.createMergers(matches, mergers)); HOOT_STR_EQUALS(1, mergers.size()); LOG_VAR(*mergers[0]); HOOT_STR_EQUALS(1, (dynamic_cast<MarkForReviewMerger*>(mergers[0]) != 0)); }
void runFindSubgraphsTest() { // See this for a visual. // https://insightcloud.digitalglobe.com/redmine/attachments/download/1638/Hootenanny%20-%20Graph%20Based%20Conflation%20-%202013-06-21.pptx ElementId a1 = ElementId::way(1); ElementId a2 = ElementId::way(2); ElementId a3 = ElementId::way(3); // unused //ElementId a4 = ElementId::way(4); ElementId b1 = ElementId::way(5); ElementId b2 = ElementId::way(5); ElementId b3 = ElementId::way(6); vector<const Match*> matches; // force the pointers to be in order which forces the set to be consistent between runs. ConstrainedFakeMatch* fm = new ConstrainedFakeMatch[4]; shared_ptr<MatchThreshold> mt(new MatchThreshold(0.5, 0.5)); matches.push_back(fm[0].init(a1, b1, 0.8, mt)->addConflict(&fm[1])); matches.push_back(fm[1].init(a2, b1, 1, mt)->addConflict(&fm[2])); matches.push_back(fm[2].init(a2, b2, 0.9, mt)); matches.push_back(fm[3].init(a3, b3, 0.9, mt)); ConstOsmMapPtr empty; OptimalConstrainedMatches uut(empty); uut.addMatches(matches.begin(), matches.end()); vector<const Match*> subsetVector = uut.calculateSubset(); MatchSet matchSet; matchSet.insert(subsetVector.begin(), subsetVector.end()); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.6, uut.getScore(), 0.001); CPPUNIT_ASSERT_EQUAL((size_t)3, matchSet.size()); CPPUNIT_ASSERT_EQUAL(true, matchSet.find(&fm[0]) != matchSet.end()); CPPUNIT_ASSERT_EQUAL(true, matchSet.find(&fm[2]) != matchSet.end()); CPPUNIT_ASSERT_EQUAL(true, matchSet.find(&fm[3]) != matchSet.end()); }
bool ScriptMatch::_isOrderedConflicting(const ConstOsmMapPtr& map, ElementId sharedEid, ElementId other1, ElementId other2) const { Isolate* current = v8::Isolate::GetCurrent(); HandleScope handleScope(current); Context::Scope context_scope(_script->getContext(current)); set<ElementId> eids; eids.insert(sharedEid); eids.insert(other1); eids.insert(other2); OsmMapPtr copiedMap(new OsmMap(map->getProjection())); CopyMapSubsetOp(map, eids).apply(copiedMap); Handle<Object> copiedMapJs = OsmMapJs::create(copiedMap); // make sure unknown1 is always first ElementId eid11, eid12, eid21, eid22; if (map->getElement(sharedEid)->getStatus() == Status::Unknown1) { eid11 = sharedEid; eid21 = sharedEid; eid12 = other1; eid22 = other2; } else { eid11 = other1; eid21 = other2; eid12 = sharedEid; eid22 = sharedEid; } boost::shared_ptr<ScriptMatch> m1( new ScriptMatch(_script, _plugin, copiedMap, copiedMapJs, eid11, eid12, _threshold)); MatchSet ms; ms.insert(m1.get()); vector<Merger*> mergers; ScriptMergerCreator creator; creator.createMergers(ms, mergers); m1.reset(); bool conflicting = true; // if we got a merger, then check to see if it conflicts if (mergers.size() == 1) { // apply the merger to our map copy vector< pair<ElementId, ElementId> > replaced; mergers[0]->apply(copiedMap, replaced); // replace the element id in the second merger. for (size_t i = 0; i < replaced.size(); ++i) { if (replaced[i].first == eid21) { eid21 = replaced[i].second; } if (replaced[i].first == eid22) { eid22 = replaced[i].second; } } // if we can still find the second match after the merge was applied then it isn't a conflict if (copiedMap->containsElement(eid21) && copiedMap->containsElement(eid22)) { ScriptMatch m2(_script, _plugin, copiedMap, copiedMapJs, eid21, eid22, _threshold); if (m2.getType() == MatchType::Match) { conflicting = false; } } } return conflicting; }